2012-12-05 6 views
7

テンプレートエイリアス(、たとえばテンプレートのエイリアスが不足しているメンバのタイプ名にあります)を含む置換に失敗した場合は、エラーが発生するはずですか?テンプレートエイリアスとファイル

クランと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; 
} 

そこで質問です:誰が正しいか、そしてなぜですか?規格によると

+0

'clang -v'とは何ですか? Clang 3.3のトランクはコードをうまくコンパイルします。 – Xeo

+0

ここでDebian clangバージョン3.1-8は、ちょうど待つ必要があるようです。ご意見ありがとうございます ! – max

+0

少しだけ簡略化するために、テンプレートエイリアスを取り除くことができますか? – David

答えて

4

:-)

おかげで、それは別名テンプレートは、すぐに交換する必要があり、その後、通常のノーマル/ SFINAEは後でTがわかっている場合typename T::member_typeに適用されるため、正確であること明らかにGCCです。

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

結果によると、clangsの動作が望まれます。Tの置換は、別名テンプレートのコンテキストで行われます(typename 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を参照してください。

+5

"会議の結果によると、clangsの動作が望ましいと思われます。" - これはそこにある "EnableIf"エイリアスを完全に殺しませんか?別名テンプレートがSFINAEソフトエラーを生成しないことは非常に望ましくないようです。 – Xeo

+0

@Xeoはい、それは悪くなるでしょう。実際、clangトランクは 'EnableIf'エイリアスを受け入れるので、askerが観察した動作はちょうどバグであり、wg21サイトの問題の要約はちょっと混乱しているようです(IMHO)。 –

+0

ええ、トランクがコードをうまくコンパイルするとコメントしているので、私は混乱しました。 – Xeo

関連する問題