模板类中的类模板特化

Fra*_*ann 4 c++ templates sfinae c++11

重新分解遗留代码我想合并彼此相关的单独模板类/结构(以避免名称空间污染).

Nested(下面)是一个帮助类MyStruct,我想进入 MyStruct.

但我无法做到这一点:

#include <type_traits>
#include <iostream>

struct YES {} ;
struct NO {};

template <typename TYPE>
struct MyStruct
{

    template <typename TYPE_AGAIN = TYPE, typename SELECTOR = NO>
    struct Nested
    {
        static void Print(void)
        {
            std::cout << "MyStruct::Nested<bool = false>::Print()" << std::endl;
        }
    };


    template <>
    struct Nested<TYPE, typename std::enable_if<std::is_integral<TYPE>::value, YES>::type>
    {
        static void Print(void)
        {
           std::cout << "MyStruct::Nested<bool = true>::Print()" << std::endl;
        }
    }; 

};
Run Code Online (Sandbox Code Playgroud)

编译器抱怨:

g++ -O0 -g3 -Wall -c -fmessage-length=0 -std=c++11 -MMD -MP -MF"main.d" -MT"main.d" -o "main.o" "../main.cpp"
In file included from ../main.cpp:8:0:
../MyStruct.h:31:12: error: explicit specialization in non-namespace scope ‘struct MyStruct<TYPE>’
  template <>
            ^
make: *** [main.o] Error 1
Run Code Online (Sandbox Code Playgroud)

实际上它也困扰我必须包括

<typename TYPE_AGAIN = TYPE>
Run Code Online (Sandbox Code Playgroud)

但没有,还有更多的抱怨:

g++ -O0 -g3 -Wall -c -fmessage-length=0 -std=c++11 -MMD -MP -MF"main.d" -MT"main.d" -o "main.o" "../main.cpp"
In file included from ../main.cpp:8:0:
../MyStruct.h:31:12: error: explicit specialization in non-namespace scope ‘struct MyStruct<TYPE>’
  template <>
            ^
../MyStruct.h:32:9: error: template parameters not used in partial specialization:
  struct Nested<typename std::enable_if<std::is_integral<TYPE>::value, YES>::type>
     ^
../MyStruct.h:32:9: error:         ‘TYPE’
make: *** [main.o] Error 1
Run Code Online (Sandbox Code Playgroud)

Rak*_*111 5

您不能在非命名空间范围内专门化模板,例如struct在您的情况下.

您必须将特化除了结构定义之外:

template<typename TYPE> template<>
struct MyStruct<TYPE>::Nested<...> {};
Run Code Online (Sandbox Code Playgroud)

但是现在你有另一个问题,如果你想在模板类中专门化一个模板,你必须为每个模板类专门化它.你不能只专门化一个成员函数,你必须专门化整个类.

所以,你需要这样做:

template<> template<>
struct MyStruct<int>::Nested<...> {};
Run Code Online (Sandbox Code Playgroud)

另外,你真的不需要SFINAE:

template<typename SELECTOR>
struct Nested; // Default invalid SELECTOR

template<>
struct Nested<YES> { /*...*/ };

template<>
struct Nested<NO> { /*...*/ };
Run Code Online (Sandbox Code Playgroud)