0

コードを考えてみましょう:それは両方のg ++​​および打ち鳴らすにコンパイルんが、それは他のテンプレートクラス内の可変長引数テンプレートクラスを特化する合法です

#include <iostream> 

template <class T> 
struct outer { 
    template <class... Args> 
    struct inner { 
     static constexpr bool value = false; 
    }; 

    template <class... Other> 
    struct inner<T, Other...> { 
     static constexpr bool value = true; 
    }; 
}; 

int main() { 
    std::cout << outer<int>::inner<int, void>::value << std::endl; 
}; 

++が、私はそれが合法であると確信していません。私が知る限り、例えば、クラス自体を明示的に専門化するのではなく、テンプレートクラスのテンプレートメソッドを特化することはできません。内部クラスのルールはどうして違うのですか?

+1

あなたはテンプレートメソッドを特化していません。あなたは部分的に完全なクラスを専門にしています。 –

答えて

2

ネストされたテンプレートクラスの部分的な特殊化はOKです:内部クラスの

template <class T> 
struct outer { 
    // template 
    template <class... Args> 
    struct inner {}; 

    // partial 
    template <class... Other> 
    struct inner<T, Other...> {}; 

    // error: explicit specialization in non-namespace scope ‘struct inner’ 
    // template <> 
    // struct inner<char, int> {}; 
}; 

明示的な(フル)特殊化のみではありません。

外側のクラスの明示的な特殊化(実際には異なるクラスである内部クラス()の専門せず)と外側と内側のクラスの明示的な特殊化が可能である:

#include <iostream> 
template <class T> 
struct outer { 
    template <class... Args> 
    struct inner 
    { 
     static void print() { std::cout << "outer<T>::inner<Args...>\n"; } 
    }; 
}; 

template <> // outer specialization 
struct outer<int> 
{ 
    template <class... Args> 
    struct inner 
    { 
     static void print() { std::cout << "outer<int>::inner<Args...>\n"; } 
    }; 
}; 

template <> // outer specialization 
template <> // inner specialization 
struct outer<int>::inner<int> // must be outside of the outer class 
{ 
    static void print() { std::cout << "outer<int>::inner<int>\n"; } 
}; 

int main() { 
    outer<char>::inner<char>::print(); 
    outer<int>::inner<char>::print(); 
    outer<int>::inner<int>::print(); 
} 

注:同じことが適用されます非可変的なネストされたテンプレートクラスに変換します。

+0

これは、完全な専門化を必要とするため、方法を専門化できない理由を説明します。しかし、ルールの背後にある理由は私にはあまり明確ではありません... –

関連する問題