Вопрос о SFINAE шаблона класса и шаблона функции - PullRequest
0 голосов
/ 26 февраля 2019

Я пытаюсь специализировать шаблон (функцию или класс) для контейнеров 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".

1 Ответ

0 голосов
/ 26 февраля 2019

Причина, по которой следующие две строки терпят неудачу, состоит в том, что нет определения ContainerHandler, которое сделало бы успешной реализацию шаблона с этими аргументами шаблона.

ContainerHandler<int> handler1; //compile error
ContainerHandler<int, int> handler2; //compile error

Если вы предоставите определение для шаблона, например, например:

template<typename T , typename = int>
struct ContainerHandler {};

Компиляция будет выполнена успешно.См. демо здесь .

РЕДАКТИРОВАТЬ:

Нет.Я ожидаю получить ошибку компиляции при вызове функции шаблона "container_handler ();"(в первой части кодов).

Параметр int_t container_handler имеет значение по умолчанию, поэтому он компилируется container_handler<int>(); Отсутствие значения по умолчанию приведет к сбою компиляции.
См. Демонстрационную версию здесь.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...