Я пытаюсь специализировать шаблон (функцию или класс) для контейнеров STL.Я использовал стандарт c ++ 14.
Для функции шаблона я пробую код следующим образом.
template<typename... Args>
using int_t = int;
template<typename T, int_t
<
typename T::value_type, //has defined the element type
typename T::iterator, //has defined the iterator
decltype(std::declval<T>().size()) //has defiend the "size()" function
//other check...
> = 0>
void container_handler()
{
}
Я думаю, что если какого-либо типа не существует в int_tфункция шаблона не будет создана, но ошибки компиляции не произойдут, когда я вызову функцию шаблона следующим образом.
container_handler<int>();
Однако при использовании шаблона класса я получаю другой результат.
template<typename... Args>
using int_t = int;
template<typename T , typename = int>
struct ContainerHandler;
template<typename T>
struct ContainerHandler<T, int_t
<
typename T::value_type, //has defined the element type
typename T::iterator, //has defined the iterator
decltype(std::declval<T>().size()) //has defiend the "size()" function
//other check...
>>
{
};
Приведенный выше код работает, ошибки компиляции возникают, когда я создаю экземпляр шаблона класса с типом, который не определил специальный тип или функцию.
ContainerHandler<int> handler1; //compile error
ContainerHandler<int, int> handler2; //compile error
ContainerHandler<vector<int>> handler3; //ok
ContainerHandler<vector<int>, int> handler4; //ok
"int_t"здесь можно заменить на «void_t» в c ++ 17.Мой вопрос заключается в том, почему правило SFINAE отличается от шаблона функции и шаблона класса.Для шаблона функции я пробую другой способ, и он работает.
template<typename... Args>
struct type_container
{
using int_t = int;
};
template<typename T, typename type_container
<
typename T::value_type, //has defined the element type
typename T::iterator, //has defined the iterator
decltype(std::declval<T>().size()) //has defiend the "size()" function
//other check...
>::int_t = 0>
void container_handler()
{
}
container_handler<int>(); //compile error
container_handler<int, 0>(); //compile error
container_handler<vector<int>>(); //ok
container_handler<vector<int>, 0>(); //ok
Я не знаю, в чем разница между использованием "int_t" и "type_container :: int_t".