2017-04-07 8 views
1

トピックに関するいくつかの質問を見てきましたが、重複してもご迷惑をかけませんでした。ネストされた指定子で使用されるテンプレート不完全型

なぜInnerは不完全なタイプですか?循環依存はどこにありますか?

P.S. (注へ

template<typename Type> 
struct Inner<Type, typename std::enable_if<std::is_same<int, Type>::value>::type> 
{ static void inner() { std::cout << "enabled\n"; } }; 

そしてcall_inner - NOT_USEDは、私が(>is_same<int, Type>NOT_USED->Typeis_same<int, A>)に2つ目の特化を変更した場合

template <class A> 
struct Outer 
{ 
    template <class NOT_USED, class Enabled = void> 
    struct Inner 
    { static void inner() { std::cout << "not enabled\n"; } }; 

    template <class NOT_USED> 
    struct Inner<NOT_USED, typename std::enable_if<std::is_same<int, A>::value>::type> 
    { static void inner() { std::cout << "enabled\n"; } }; 
}; 

template <class A> 
void call_inner(A& a) 
{ 
    Outer<A>::template Inner<void>::inner(); // #1 
} 

int main() 
{ 
    int intVar = 10; 
    double doubleVar = 1; 
    call_inner(intVar); // OK 
    call_inner(doubleVar); // Error at #1: incomplete type ‘Outer<double>::Inner<void>’ used in nested name specifier 
} 

UPDATE

部分特殊化を維持するためにプレースホルダークラスですInner<void> - >Inner<T>

template <class T> 
void call_inner(T& t) 
{ 
    Outer<T>::template Inner<T>::inner(); 
} 

すべてコンパイルされます。何故ですか?どうやら、Outerテンプレートパラメータの依存関係は、どうにかしてインスタンス化プロセスを変更しますか?

答えて

0

クランのエラーメッセージがより明確である:

ess.cpp:11:52: error: no type named 'type' in 
     'std::__1::enable_if<false, void>'; 'enable_if' cannot be used to disable 
     this declaration 
    ...Inner<NOT_USED, typename std::enable_if<std::is_same<int, A>::value>::type> 
              ^~~~~~~~~~~~~~~~~~~~~~~~~~~ 
ess.cpp:18:5: note: in instantiation of template class 'Outer<double>' requested 
     here 
    Outer<A>::template Inner<void>::inner(); // #1 
    ^
ess.cpp:26:5: note: in instantiation of function template specialization 
     'call_inner<double>' requested here 
    call_inner(doubleVar); // Error at #1: incomplete type <BF>Outer<dou... 

あなたは== int型にインスタンス化を制限enable_ifを持っているとして、あなたはOuter<double>::Inner<void>をインスタンス化することはできません。

+0

SFINAEはここに適用されないのはなぜ?更新された質問を参照してください。 'Inner'インスタンス化の違いは何ですか? – DimG

0

可能修正:

template <class A> 
struct Outer 
{ 
    template <class NOT_USED, typename T = A, class Enabled = void> 
    struct Inner 
    { static void inner() { std::cout << "not enabled\n"; } }; 

    template <class NOT_USED, typename T> 
    struct Inner<NOT_USED, T, 
       typename std::enable_if<std::is_same<int, T>::value 
             && std::is_same<A, T>::value>::type> 
    { static void inner() { std::cout << "enabled\n"; } }; 
}; 
+0

'Outer'テンプレートパラメータの依存性が'内部のインスタンス化の振る舞いを変更する理由とその理由について詳しく説明できますか? – DimG

+1

'std :: is_same 'は 'Inner'に依存しませんが、' std :: is_same 'はそれに依存しません。 1つのケースではハードエラーが発生し、もう1つのケースでは代替エラーが発生します(とSF INAE :)。 – Jarod42

関連する問題