2017-06-23 15 views
6

で-std = C++ 1Zでの作業私は次のコードすることを見出した:-std=c++1zg++-7でコンパイルされたときテンプレートテンプレート部分特化のみG ++

#include <iostream> 
#include <vector> 

template <typename T> 
struct X : std::false_type {}; 

template <template <typename> class Y, typename U> 
struct X<Y<U>> : std::true_type {}; 

int main() { 
    if (X<int>()) 
    std::cout << "wrong\n"; 

    if (X<std::vector<double>>()) 
    std::cout << "correct\n"; 

    return 0; 
} 

のみcorrectを印刷します。他のバージョンのg++,clang++または他のstdフラグは正しく生成されません。

これは現在の実装のバグですか?このコードは何も印刷しないか、C++で何か変更されていますので、このコードは期待通りに動作しますか?

+0

おもしろいことに、 'Y'は可変個の引数をとると' -std = C++ 1z'のclangに 'correct'と' -std = C++ 17のgccのためには何も表示されません':) – Rakete1111

+0

' g ++ - 7'で 'correct'を表示しています。 – Svalorzen

答えて

9

これが動機であった、例とC++ 17にP0522の適用の結果である:以前

template <template <int> class> void FI(); 
template <template <auto> class> void FA(); 
template <auto> struct SA { /* ... */ }; 
template <int> struct SI { /* ... */ }; 
FI<SA>(); // OK; error before this paper 
FA<SI>(); // error 

template <template <typename> class> void FD(); 
template <typename, typename = int> struct SD { /* ... */ }; 
FD<SD>(); // OK; error before this paper (CWG 150) 

、[temp.arg.template]で表現種類が厳密に一致するテンプレートテンプレートパラメータが必要です。だから、与えられた:

template <template <class > class P> class X; 

template <class T> class A; 
template <class T, class U=T> class B; 
template <class... > class C; 

X<A>は明らかに大丈夫ですが、Pは、1つのテンプレートパラメータを期待してCがかかるためBは、2つのテンプレートパラメータ(関係なく、1がデフォルト設定されている場合!)とX<C>がかかるためX<B>が病気に形成されたのは、病気に形成されています1つのパラメータでCを作成することができます)

新しい用語は、テンプレートテンプレートパラメータが引数。これにより、X<B>X<C>の両方が機能します。

したがって、C++ 17では、X<std::vector<double>>が特殊化を選択する必要があります。しかし、C++ 17の前に、それはプライマリを選択する必要があります。 gccは正しいことをやっています。

+0

その用紙を一目見てみると、これは非型テンプレートパラメータのようです。この場合、これがどのように関連しているかについて、より具体的に/愚かにすることができますか? – xaxxon

+0

@xaxxonもっと長い視点?これは、テンプレートテンプレート以外のテンプレートパラメータに関するものではありません。テンプレートテンプレートに関するものです。 'FD ()'の例は、OPが行っていることとまったく同じです。 – Barry

+0

ありがとう、私は今理解しています。 – xaxxon

関連する問題