2

g(unsigned long)Clang 3.0 は次のコードを拒否し、見つからないことを訴えます。GCC 4.8 はエラーなしでそれを受け入れます。

void g(int*);

void f()
{
    g(sizeof(int) - sizeof(int)); // ok, evaluates to 0
}

template<typename T>
struct A
{
    void f()
    {
        g(sizeof(T) - sizeof(T)); // error: no matching function
    }
};

標準を読んだところ、「g」は従属名ではなく、clang のように検索してすぐにバインドする必要があることがわかりました。それでも、標準で指定された動作は間違っているように見えgます。そうでなければ、インスタンス化時に正しくバインドされるからです。

[temp.dep]
[...] 次の形式の式で は、postfix-expression が id-expression の場合、id-expression は、expression-list 内のいずれかの式が型である場合に依存する名前を示します
postfix-expression ( expression-list)
-dependent 式 (14.6.2.2)、または id-expression の unqualified-id が、テンプレート引数のいずれかがテンプレート パラメーターに依存する template-id である場合。演算子のオペランドが型依存式の場合、演算子は依存名も示します。このような名前はバインドされておらず、テンプレート定義のコンテキストとインスタンス化のポイントのコンテキストの両方で、テンプレートのインスタンス化のポイント (14.6.4.1) で検索されます。

このシナリオでの準拠動作は何ですか?

4

1 に答える 1

1

C++ 標準の既知の欠陥により、この動作は規定されていないことが判明しました。

http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html

DR 903. 値依存の整数ヌルポインタ定数

提案された解決策は、ヌル ポインター定数としてリテラル '0' のみを許可するように標準の文言を変更することですが、これは 'false' を使用する既存のコードを破壊することを意味するため、現在検討中です。

GCC は、「g」を従属名として扱うことでこれを解決しているようです。対照的に、Clang は、値に依存する式がヌル ポインター定数式になることは決してないという規則のようです。正しい動作が指定されていないため、どちらのアプローチも厳密には正しくありません。

于 2013-08-04T22:24:54.627 に答える