2016-11-28 9 views
1

次のコードを考慮して:テンプレートエイリアス宣言が新しいタイプのファミリに解決される場合

Xのようにテンプレートエイリアスを使用するとどうなりますか? ZはYのエイリアスなので、専門化Xはまだ使用されていますか? テンプレートエイリアスを使用すると、テンプレートエイリアスの宣言が新しいタイプのファミリに解決されるとどうなりますか?

#include <iostream> 

template <template <typename> class> 
struct X { 
    X() { std::cout << "1"; } 
}; 

template <typename> 
struct Y {}; 

template <typename T> 
using Z = Y<T>; 

template <> 
struct X<Y> { 
    X() { std::cout << "2"; } 
}; 

int main() { 
    X<Y> x1; 
    X<Z> x2; 
} 

output :21 
+1

Z'は単に 'Y'の別名である'として私は、 '22'を印刷することを期待します。 g ++は '22'を出力しますが、' 21'を出力します... –

+0

はい、なぜあなたは別のものになるのですか? – Adib

+0

私は言葉が前にはっきりしていないと思っていますが、同じ順序のテンプレート引数)。 – Jarod42

答えて

3

エイリアスは単なるエイリアスであり、新しいタイプのファミリを導入しません。実際には、あなたのコードを実行して22を印刷する - ZYのエイリアスであるため、特殊化は2回ヒットします。

残念ながら、g ++は22を期待どおりに印刷しますが、clangは21と表示します。私はそれがbug #26093のためだと思う。実際には、通常のテンプレートにtemplateテンプレートを変換すると、発生するバグを防ぐ:

template <typename> 
struct X { 
    X() { std::cout << "1"; } 
}; 

struct Y {}; 
using Z = Y; 

template <> 
struct X<Y> { 
    X() { std::cout << "2"; } 
}; 

int main() { 
    X<Y> x1; 
    X<Z> x2; 
} 

wandbox example

+0

しかし、標準の§14.5.7パラグラフ1によれば、テンプレートエイリアス宣言は新しいタイプのファミリに解決されます。特殊化は使用できません。最初のテンプレート宣言が代わりに使用され、1を印刷します。imはそのバグや新しい標準をC++で混乱させました14 – Adib

+0

標準では、["*ファミリー" *(https:// timsong-cpp.github.io/cppwp/temp.alias)ではなく、「*新しい**タイプのファミリー」*です。 –

+0

ワンドボックスは私に21を与えますhttp://melpon.org/wandbox/permlink/n5vIKLCGFXO6Qvm7 – Adib

関連する問題