Передать шаблон класса в качестве аргумента шаблона

Можно ли передать шаблон класса (например, std::vector, не создавая его экземпляр, например std::vector<int>) в качестве аргумента шаблона? Я хочу написать тип, который проверяет, является ли данный тип экземпляром данного шаблона. Я знаю, что компилятор не позволяет передавать неэкземплярный шаблон как есть, но мне интересно, есть ли лучший обходной путь, чем то, что я получил.

Моя реализация (обратите внимание, я стираю TArgs в самом низу):

#include <type_traits>

template <typename Instance, typename Template>
struct IsInstanceOf : std::false_type {};

template <
      template <typename...> typename Instance,
      template <typename...> typename Template, 
      typename... IArgs,
      typename... TArgs>
struct IsInstanceOf<Instance<IArgs...>, Template<TArgs...>>
    : std::is_same<Instance<IArgs...>, Template<IArgs...>> {};

Эта реализация работает, но мне нужно создать экземпляр шаблона с некоторым типом, например:

IsInstanceOf<std::vector<float>, std::vector<void>>::value

Поведение соответствует ожидаемому, но мне интересно, есть ли что-то лучше, например

IsInstanceOf<std::vector<float>, std::vector<>>::value 
// since this is illegal
IsInstanceOf<std::vector<float>, std::vector>::value

Вот ссылка на пример.


person Timo    schedule 15.12.2018    source источник
comment
Обычно требуется что-то вроде специализации или подхода на основе SFINAE, но вам нужно объяснить, в чем заключается ваша настоящая проблема. Нет, проблема не в использовании неэкземплярных шаблонов, как вы их описываете. Это проблема, ответом на которую, как вы считаете, является использование неконкретизированных шаблонов, поэтому вы в конечном итоге спрашиваете об этом, а не о своей реальной проблеме. Вместо этого попробуйте описать исходную проблему здесь.   -  person Sam Varshavchik    schedule 15.12.2018
comment
@SamVarshavchik Первоначально я хотел проверить, является ли аргумент шаблона функции std::shared_ptr какого-либо типа. Но потом я подумал, что могу как-то его обобщить (включить в свою библиотеку utils).   -  person Timo    schedule 15.12.2018
comment
Не правильнее ли было бы сказать: передать шаблон класса в качестве аргумента шаблона? Неконкретизированный шаблон не имеет смысла, и поэтому его будет сложно найти.   -  person anonymous    schedule 16.12.2018


Ответы (1)


#include <type_traits>

template <typename T, template <typename...> typename Template>
struct IsInstanceOf : std::false_type {};

template <
      template <typename...> typename Template,
      typename... TArgs>
struct IsInstanceOf<Template<TArgs...>, Template>
    : std::true_type {};

#include <vector>
static_assert(IsInstanceOf<std::vector<float>, std::vector>::value);
static_assert(!IsInstanceOf<int, std::vector>::value);
#include <string>
static_assert(!IsInstanceOf<std::string, std::vector>::value);
static_assert(IsInstanceOf<std::string, std::basic_string>::value);

int main() {}

https://wandbox.org/permlink/PTXl0KoxoJ2aFJfK

person Nikita Kniazev    schedule 15.12.2018