Выполнение static_assert, что тип шаблона является другим шаблоном

Как мне static_assert ? Может быть, Boost поддерживает его, если не C ++ или новые функции в C ++ 11?

 template struct foo {}; template struct bar { static_assert(FooType is indeed foo for some T,"failure"); //how? }; 

Вы могли бы сделать что-то в этом направлении. Учитывая черту, которая может проверить, является ли class экземпляром шаблона classа:

 #include  template class TT> struct is_instantiation_of : std::false_type { }; template class TT> struct is_instantiation_of, TT> : std::true_type { }; 

Используйте его в своей программе следующим образом:

 template struct foo {}; template struct bar { static_assert(is_instantiation_of::value, "failure"); }; int main() { bar b; // ERROR! bar> b; // OK! } 

Если вы хотите, вы можете обобщить это, чтобы определить, является ли class экземпляром шаблона с любым количеством параметров (типа), например:

 #include  template class TT, typename T> struct is_instantiation_of : std::false_type { }; template class TT, typename... Ts> struct is_instantiation_of> : std::true_type { }; template struct bar { static_assert(is_instantiation_of::value, "failure"); }; 

Затем вы будете использовать его таким образом в своей программе:

 template struct bar { static_assert(is_instantiation_of::value, "failure"); }; int main() { bar b; // ERROR! bar> b; // OK! } 

Вот живой пример .

Как писал кто-то другой,

 template class TT> struct is_specialization_of : std::false_type { }; template class TT, typename... Ts> struct is_specialization_of, TT> : std::true_type { }; 

Однако будьте осторожны, что это работает только для classов шаблонов, параметры шаблонов которых являются все typenames! Представлены

 typedef std::array MyArray; static_assert(is_specialization_of::value, ""); 

он просто не будет компилироваться вообще.

Я считаю, что C ++ 11 / C ++ 14 / C ++ 17 не имеет способа справиться с этим ограничением.

Некоторые небольшие улучшения по сравнению с другими ответами:

  • имя фактически имеет смысл в отношении порядка параметров
  • правильно справляется со const , volatile и ссылочными типами через std :: decay
  • реализует переменную _v constexpr стиле C ++ 14
  • принимает произвольное количество типов для тестирования (тесты для ALL)

Я намеренно не помещал std :: decay_t в is_template_for_v, потому что черта типа должна работать одинаково независимо от того, вызвана ли она суффиксом _v или нет.

Для этого требуется C ++ 17 для std::conjunction conj, но вы можете либо удалить вариационную функцию, либо реализовать собственное conjunction используя c ++ 11/14.

 template class tmpl, typename T> struct _is_template_for : public std::false_type {}; template class tmpl, class... Args> struct _is_template_for> : public std::true_type {}; template class tmpl, typename... Ts> using is_template_for = std::conjunction<_is_template_for>...>; template class tmpl, typename... Ts> constexpr bool is_template_for_v = is_template_for::value; 

Применение:

 static_assert(is_template_for_v>); // doesn't fire 
Interesting Posts
Давайте будем гением компьютера.