Включить структуру, если enable_if определяет, что T является контейнером? - PullRequest
2 голосов
/ 31 марта 2019

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

Вот код, который я написал:

template<typename T> 
struct is_container : std::integral_constant<bool, has_const_iterator<T>::value && has_begin_end<T>::beg_value && has_begin_end<T>::end_value> { };

template<typename T, typename Enable = void>
struct Cont;

template <typename T>
struct Cont<T, typename std::enable_if<is_container<T>::value>>
{
  Cont(const std::string &n) : name(n) {}
  std::string name;
};

Однако, когда я пытаюсь записать в main:

int main()
{
  Cont<std::vector<int>> myContainer("Vector");
}

Я получаю ошибку компилятора: Cont<std::vector<int> > myContainer has initializer but incomplete type. Я застрял на том, куда идти с этим, потому что, если я удаляю std::enable_if из параметра шаблона, он компилируется просто отлично.Это заставляет меня поверить, что я делаю что-то не так с std::enable_if или я упускаю что-то довольно простое.

Я пытаюсь добиться следующего:

int main()
{
  Cont<std::vector<int>> myContainer("Vector"); //happily compiles
  Cont<int> badContainer("Bad"); // will not compile
}

Как можноЯ достиг этого?

1 Ответ

2 голосов
/ 01 апреля 2019

Это заставляет меня поверить, что я делаю что-то не так с std::enable_if или я упускаю что-то довольно простое.

Точно.

Вы забыли ::type

template <typename T>  // add this ---------------------------vvvvvv
struct Cont<T, typename std::enable_if<is_container<T>::value>::type>
{
  Cont(const std::string &n) : name(n) {}
  std::string name;
};

Начиная с C ++ 14, вы также можете использовать std::enable_if_t (чтобы вы могли удалить ::type и предыдущие typename)

template <typename T>
struct Cont<T, std::enable_if_t<is_container<T>::value>>
{
  Cont(const std::string &n) : name(n) {}
  std::string name;
};
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...