2013-12-18 5 views
18

あいまいな関数id-expressionのC++ 11初期化子?以下のC++コード11で

void f(int) {} 
void f(double) {} 

void (*p)(int) = f; 

は2つの機能があります。

第3のf識別子はid式であり、初期化子はpです。 5.1.1p8 [expr.prim.general]/8で

それは言う:

[ID-発現]の種類は、識別子のタイプです。 結果は識別子で示されるエンティティです。エンティティが関数、変数、またはデータメンバーの場合は結果が左辺値、それ以外の場合は正値です。

fは、2つの異なるタイプの2つの異なるエンティティを参照している可能性があるため、「エンティティ」または「タイプ」はありません。

このような状況に対処する標準のテキストがありますか?

実装はこれを拡張として曖昧にするか、どこかで必要とされますか? (いくつかの他のテキストのないものは、実装が曖昧としてF IDの発現を拒否することができることを主張できる)

+0

私には証拠はありませんが、私はこれがあいまいではないと思います。オーバーロードされた関数が** f(T1)対f(T2)と呼ばれるときに何が起こるかを考えてみましょう。ここで、コンパイラはどの関数(ポインタ)を呼び出す必要があるかを決定する必要があります。 IMOこれは同様のケースです。 (そして+1、ついに良いC++の質問です!) –

+0

これは標準で必要ですが、それを扱うテキストは覚えていません。私を検索させてください。 – Nawaz

+0

@DietmarKühlまあ、それは私が言っていることです... –

答えて

17

(13.4§で)規格が定義する:

オーバーロードされた関数名を使用せず引数は、関数への特定のコンテキスト、関数へのポインタ、またはオーバーロードセットの特定の関数に対する メンバ関数へのポインタで、 で解決されます。 関数テンプレート名は、そのようなコンテキストでオーバーロードされた 関数のセットに名前を付けると見なされます。 タイプが、 コンテキストで必要とされるターゲットタイプのファンクションタイプと同一のものです。

強調鉱山。引用した後

は、例は(§13.4/5時)があるあなたに似ている:

​​

限り単項&に関しては、標準がその(§5.3で指定します.1/6とjogojapanのおかげで):

多重定義関数のアドレスは、一意01である多重定義関数のバージョンを判断するコンテキスト で撮影することができますを参照してください。

も(§13.4/1で)を省略することができる。

オーバーロードされた関数名 &オペレータが先行することができます。

(やはり強調する鉱山)あなたの例のように。

+0

良いですが、単一の文章では、これは関数呼び出しと' static_cast'での動作を説明しています! –

+1

+1。偉大な引用。 :-) – Nawaz

+0

間違いなく正しい答えです。 5.3.1/6への参照を追加すると、アドレス演算子のアプリケーションが「特定のコンテキスト」の1つであることが明確になります。 (あなたが引用している例でもそれを明確にするかもしれませんが) – jogojapan

関連する問題