Порядок утилит шаблона переменной типа __vits * _v не компилируется - PullRequest
8 голосов
/ 20 сентября 2019

Увидев этот ответ , я попытался придумать утилиту переменный шаблон для кода из него:

template <class T, template <class...> class Template>
struct is_specialization : std::false_type {};

template <template <class...> class Template, class... Args>
struct is_specialization<Template<Args...>, Template> : std::true_type {};

И реализовать его так:

template <template <class...> class Template, class... Args>
constexpr bool is_specialization_v = is_specialization<Template<Args...>, Template>::value;

, потому что именно так я видел подобные утилиты для реализации в заголовочном файле <type_traits>.Например:

template <typename _Tp, typename _Up>
  inline constexpr bool is_same_v = is_same<_Tp, _Up>::value;
template <typename _Base, typename _Derived>
  inline constexpr bool is_base_of_v = is_base_of<_Base, _Derived>::value;
template <typename _From, typename _To>
  inline constexpr bool is_convertible_v = is_convertible<_From, _To>::value;

и т. Д. ( GCC 8.2.0 реализация от MinGW )

Но проблема в том, что, хотя синтаксис ::value работает,Синтаксис *_v не:

int main() {
    bool foo = is_specialization<std::vector<int>, std::vector>::value; // No problem
    bool bar = is_specialization_v<std::vector<int>, std::vector>;      // compilation error!

    std::cout << foo << ' ' << bar;
}

Это приводит к следующей ошибке:

error: type/value mismatch at argument 1 in template parameter list for 'template<template<class ...> class Template, class ... Args> constexpr const bool is_specialization_v<Template, Args ...>'
 bool bar = is_specialization_v<std::vector<int>, std::vector>;      // compilation error!
            ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
note:   expected a class template, got 'std::vector<int>'
error: type/value mismatch at argument 2 in template parameter list for 'template<template<class ...> class Template, class ... Args> constexpr const bool is_specialization_v<Template, Args ...>'
expected a type, got 'vector'

Почему это так?Если честно, ошибка кажется мне справедливой и заставляет меня думать , как именно работает код в вышеупомянутом ответе.Он ожидает class шаблон и пакет параметров, но ему дается a class, затем пакет.С другой стороны, он специализируется на комбинации этих двух типов, и это меня немного смущает.Я хотел бы знать:

  • Что такое процесс удержания здесь?Связанный ответ не раскрывает подробно, как работает код.
  • Как ввести в этом случае утилиту шаблона переменных *_v?

Ответы [ 2 ]

6 голосов
/ 20 сентября 2019

Давайте сравним параметры шаблона varaible ...

template <template <class...> class Template, class... Args>
constexpr bool is_specialization_v = is_specialization<Template<Args...>, Template>::value;

с аргументами

is_specialization_v<std::vector<int>, std::vector>

Вы объявили, что он сначала принимает шаблон, но затем вы передаететип.Тогда вы объявили, что он принимает пакет типов, но теперь вы пропустите шаблон.Проблема в том, что вы запутались и внедрили переменную, как специализацию основной черты.Он не принимает параметр для передачи в качестве аргументов для размещения в специализации.Он должен принять те же параметры, что и основной, и просто переслать их:

template <class T, template <class...> class Template>
constexpr bool is_specialization_v = is_specialization<T, Template>::value;
5 голосов
/ 20 сентября 2019

Шаблон переменной должен иметь те же параметры шаблона, что и исходный шаблон: <class T, template <class...> class Template>.Я не уверен, почему вы использовали параметры шаблона из специализации.

Это должно выглядеть так:

template <class T, template <class...> class Template>
constexpr bool is_specialization_v = is_specialization<T, Template>::value;
...