Когда я специализируюсь на классе, как я могу взять другое количество параметров шаблона? - PullRequest
0 голосов
/ 13 сентября 2018

Я только что задал этот вопрос: Можно ли получить объект-владелец параметра шаблона функции-члена? и Якк - Адам Невраумонт ответ имел код:

template<class T>
struct get_memfun_class;

template<class R, class T, class...Args>
struct get_memfun_class<R(T::*)(Args...)> {
    using type=T;
};

Это явно начальная декларация, а затем специализация struct get_memfun_class. Но я чувствую себя неуверенно: Может ли специализация иметь различное количество параметров шаблона?

Например, что-то вроде этого законно?

template<typename T>
void foo(const T&);

template<typename K, typename V>
void foo<pair<K, V>>(const pair<K, V>&);

Нет ли требований, чтобы специализации принимали одинаковое количество параметров?

Ответы [ 2 ]

0 голосов
/ 13 сентября 2018

Вы, кажется, путаете параметры шаблона явной специализации и аргументы шаблона, которые вы используете для специализации шаблона.

template<class T> // one argument
struct get_memfun_class; // get_memfun_class takes one template (type) argument

template<class R, class T, class...Args>
struct get_memfun_class<R(T::*)(Args...)> {
//                      ^^^^^^^^^^^^^^^^
//                      one type argument
    using type=T;
}; // explicit specialization takes one template argument

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

template <>
struct get_memfun_class<void>;
//                      ^^^^
//                    one type argument

Здесь то же самое. Да, явная специализация не принимает параметров, но это просто означает, что не нужно выводить ничего, и вы действительно пишете параметр шаблона (void), и поэтому количество аргументов шаблона специализации совпадает с аргументами основного шаблона .

Ваш пример неверен, потому что вы не можете частично специализировать функции.

0 голосов
/ 13 сентября 2018

Нет ли требований, чтобы специализации принимали одинаковое количество параметров?

Есть;и удовлетворен в вашем примере.

Когда вы пишете

template<class T>
struct get_memfun_class;

, вы говорите, что get_mumfun_class - это шаблон struct с единственным шаблоном typename аргумент;и когда вы пишете

template<class R, class T, class...Args>
struct get_memfun_class<R(T::*)(Args...)> {
    using type=T;
};

, вы определяете специализацию, которая получает один аргумент typename шаблона в форме R(T::*)(Args...).

Из одного типа R(T::*)(Args...) вы можете вывести болееодин шаблон параметров (R, T и variadic Args..., в этом примере), но тип R(T::*)(Args...) (метод класса, который получает список переменных variadic) остается один.

Например, что-то вроде этого законно?

template<typename T>
void foo(const T&);

template<typename K, typename V>
void foo<pair<K, V>>(const pair<K, V>&);

Нет, но (как написано в комментариях) вторая не является частичной специализацией класса / структуры (где * 1031)* остаются единым типом), это законно;это шаблон функция частичная специализация запрещена.

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

 template<>
 void foo<std::pair<long, std::string>(const std::pair<long, std::string>&);

, как и законно полная специализация для get_memfun_class (для примера)

template<>
struct get_memfun_class<std::pair<long, std::string>> {
    using type=long long;
};
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...