10

次のコード

#include <iostream>
#include <utility>

template<typename F, typename... T>
struct Wrapper{ };

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

template<typename... T>
struct is_wrapper<Wrapper<T...>> : std::true_type {};

//template<typename F, typename... T>
//struct is_wrapper<Wrapper<F, T...>> : std::true_type {};

int main()
{
    Wrapper<int, double> w;

    std::cout << is_wrapper<decltype(w)>::value << std::endl;
}

0 を出力します。ただし、中央の 2 行のコメントを外すと、1 が出力されます。

常に 1 を出力しないのはなぜですか? 2 番目の部分的な特殊化は、明らかに 3 番目の (コメントされた) 部分的な特殊化によってのみカバーされるケースをカバーするべきではありませんか?

4

3 に答える 3

0

あなたの問題をよく理解していれば、それは単なる専門化の優先事項です.

is_wrapper<decltype(w)>

2つのテンプレートで特化可能:

template<typename T> // exact specialization
template<typename... T> // variadic specialization with one parameter 

この場合、コンパイラは正確な特殊化を優先して選択するため、テンプレートは決して固定されません。

于 2014-05-31T08:09:01.540 に答える
0

通常、特殊化されるテンプレートを作成するときは、最初に前方宣言を使用し、ケースが特殊化に属することを宣言します。あなたの場合、空のケースなしで可変個引数テンプレートを作成しようとしていることを理解しています(つまり、少なくとも1つのタイプを持つことができる可変個引数テンプレート)。

私はあなたが正しいと思うので、あなたのコードは私を驚かせました.あなたの特性の完全な可変個の特殊化は穴のケースと一致します...最初に、私はあなたの特性クラスの前方宣言を使用しようとし、完全な可変個の特殊化のみを定義しようとしました(したがって、特性のパラメーターはWrapper、コンパイルが失敗するインスタンスではありません)。そして、それがまさに起こったことであり、再び私を失望させました:

#include <iostream>
#include <utility>

template<typename F , typename... T>
struct Wrapper {};

template<typename T>
struct is_wrapper;

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

template<typename... T>
struct is_wrapper<Wrapper<T...>> : std::true_type {};

//template<typename F, typename... T>
//struct is_wrapper<Wrapper<F, T...>> : std::true_type {};

using my_wrapper_type = Wrapper<int,double>;

int main()
{   
    std::cout << std::boolalpha  << is_wrapper<my_wrapper_type>::value << std::endl;
}//"Invalid use of incomplete type" ^^^^^^^^^^^^^^^^^^^^^^^^^^^

Wrapper最後に、クラスの前方宣言メソッドで試してみました。そして驚くべきことに、それは機能します:

#include <iostream>
#include <utility>

template<typename... T>
struct Wrapper;

template<typename F, typename... T>
struct Wrapper<F,T...>{ };


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

template<typename... T>
struct is_wrapper<Wrapper<T...>> : std::true_type {};

//template<typename F, typename... T>
//struct is_wrapper<Wrapper<F, T...>> : std::true_type {};


using my_wrapper_type = Wrapper<int,double>;

int main()
{
    std::cout << std::boolalpha  << is_wrapper<my_wrapper_type>::value << std::endl;
}

これは以下を出力します:

真実

ideoneで実行されているコードは次のとおりです。

誠に申し訳ありませんが、あなたのコードが失敗し、私のコードが機能する理由がわかりません。コンパイラのバグですか、それとも何か不足していますか? 知らない。

于 2013-08-11T15:07:22.790 に答える