为什么这个类的部分模板专业化代码不起作用?

时间:2016-04-27 08:34:51

标签: c++ templates visual-studio-2015

#include <typeinfo>

struct NullType {};

template < typename T0, typename T1, typename T2 >
class Test
{
public:
    typedef int Type;
};

template< typename T0, typename T1 >
class Test< T0, T1, NullType >
{
public:
    typedef unsigned char Type;
};

template< typename T0 >
class Test< T0, NullType, NullType >
{
public:
    typedef double Type;
};

int main()
{
    typedef Test<int, int>::Type TargetType;

    printf("%s\n", typeid(TargetType).name());

    return 0;
}

我使用visual C ++ 2015来编译这个C ++代码,但它得到了一个编译错误:

>test.cpp(34): error C2976: 'Test' : too few template arguments
>test.cpp(13): see declaration of 'Test'
>test.cpp(34): error C2955: 'Test' : use of class template requires template argument list
>test.cpp(13): see declaration of 'Test'

我希望Test<int, int>使用类Test的第二个专业化。 但似乎它不起作用。我做错了什么?

这是有效的代码:

#include <typeinfo>

struct NullType {};

template < typename T0 = NullType, typename T1 = NullType, typename T2 = NullType>
class Test
{
public:
    typedef int Type;
};

template< typename T0, typename T1 >
class Test< T0, T1, NullType >
{
public:
    typedef unsigned char Type;
};

template< typename T0 >
class Test< T0, NullType >
{
public:
    typedef double Type;
};

int main()
{
    typedef Test<int, int>::Type TargetType;

    printf("%s\n", typeid(TargetType).name());

    return 0;
}

1 个答案:

答案 0 :(得分:3)

请注意,由于c ++ 11和可变参数模板,您可以

template <typename ... Ts> struct Test;

template <typename T0, typename T1, typename T2>
struct Test<T0, T1, T2>
{
    using Type = int;
};

template <typename T0, typename T1>
struct Test<T0, T1>
{
    using Type = unsigned char;
};

template <typename T0>
struct Test<T0>
{
    using Type = double;
};

int main()
{
    using TargetType = Test<int, int>::Type;
    // Compile time check:
    static_assert(std::is_same<unsigned char, TargetType>::value, "unexpected type");
    // runtime check:
    std::cout << typeid(TargetType).name() << std::endl;
}

Demo