12

テンプレートエイリアス(たとえば、以下のコードスニペットのように、欠落しているメンバータイプ名のテンプレートエイリアス)に関連する置換が失敗した場合、エラーをトリガーする必要がありますか?

Clangとgccはこれについて意見が一致していないようです:

// some types
struct bar { };

struct foo {
    typedef void member_type;
};


// template alias
template<class T>
using member = typename T::member_type;


template<class T>
void baz(... ) { }

// only works for gcc, clang fails with: no type named 'member_type'
// in 'bar'
template<class T>
void baz( member<T>* ) { }


int main(int, char** ) {

    baz<bar>(0);            // picks first
    baz<foo>(0);            // picks second

    return 0;
}

したがって、問題は、誰が正しいのか、そしてその理由は何かということです。

ありがとう :-)

4

1 に答える 1

5

規格によると、エイリアス テンプレートをすぐに置き換える必要があり、後で通常の SFINAE が判明しtypename T::member_typeたときに適用されるため、正しいのは明らかに GCCTです。

しかし、現在これには問題があります。 http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#1554を参照してください。

会議の結果によると、clangs の動作が望ましいようですTtypename T::member_typeこれが実装方法である場合、パラメータ型パターンがどこから発生したかのソースとして参照される必要があります)。


これは、インスタンス化のセマンティクスに影響を与える可能性のあるパターンが定義時に破棄される別の状況に似ています。

template<int I>
void f(int x[I]);

int main() {
  f<0>(nullptr);
}

int*この場合も、私の意見では、パラメーターがすぐに置き換えられ、インスタンス化が機能することは規範的に明確です。http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#1322を参照してください。

于 2012-12-05T19:26:15.257 に答える