2016-04-27 3 views
1
#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++, но получаю сообщение об ошибке компиляции:Почему этот класс неполный шаблон специализации шаблона не работает?

1>testttt.cpp(34): error C2976: 'Test' : too few template arguments 
1>testttt.cpp(13) : see declaration of 'Test' 
1>testttt.cpp(34): error C2955: 'Test' : use of class template requires template argument list 
1>testttt.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; 
} 
+0

ОК, я понимаю, частичная специализация шаблонов просто предоставляет специальный класс, когда мы его используем, мы должны предоставить все параметры шаблона, поэтому в этом случае я могу установить параметр по умолчанию для класса по умолчанию. он будет хорошо работать: – Hikari

ответ

2

Обратите внимание, что начиная с C++ 11 и VARIADIC шаблон, вы можете сделать

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

Смежные вопросы