c ++ 11 — шаблон C ++: не может соответствовать последнему шаблону в шаблоне класса variadic

Я изучаю шаблон C ++ 11 variadic и создал структуру шаблона для вычисления максимального числа заданного списка и попробовал:

#include <iostream>
#include <type_traits>

template <int a, int b, int... cs>
struct max: std::integral_constant<int, (a>b? max<a, cs...>::value: max<b, cs...>::value)> {};
template <int a, int b>
struct max<a, b>: std::integral_constant<int, (a>b? max<a>::value: max<b>::value)> {};
template <int a>
struct max<a>: std::integral_constant<int, a> {};

int main() {
std::cout << max<2,1,5,7>::value << std::endl;
return 0;
}

но г ++ жалуется

test.cc:7:58: error: wrong number of template arguments (1, should be at least 2)
struct max<a, b>: std::integral_constant<int, (a>b? max<a>::value : max<b>::value)> {};

test.cc:9:13: error: wrong number of template arguments (1, should be at least 2)
struct max<a>: std::integral_constant<int, a> {};

Я могу заставить его работать, добавив простое объявление впереди:

template <int...>
struct max;

и измените первый шаблон выше на:

template <int a, int b, int... cs>
struct max<a, b, cs...>: ...

Я сослался на cppreference: https://en.cppreference.com/w/cpp/language/partial_specialization#Partial_ordering
но я не могу найти никакого полезного объяснения для моего случая.

Проблема может исходить из последнего шаблона (max<a>) только с одним параметром шаблона, который не является специализированной версией основного.

Итак, мой вопрос:

Зачем max<a> не может быть сопоставлено? Есть ли какие-либо правила или стандарты, касающиеся этого?

================================================== ===============

хорошо, я нашел стандарты C ++ (Документ № N4659), в которых говорится:

[Примечание: Частичные специализации шаблонов классов найдены
ищем первичный шаблон класса и затем с учетом все частичное
специализации этого шаблона. Если объявление-использование называет класс
шаблон, частичные специализации введены после
с помощью объявления-объявления эффективно видно, потому что основной шаблон
виден (17.5.5). — конец примечания]

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

4

Решение

Когда вы определяете шаблон класса как:

template <int a, int b, int... cs> struct max { ... };

Следующее является действительной специализацией.

template <int a, int b> struct max<a, b> { ... };

Однако следующего нет.

template <int a> struct max<a> { ... };

поскольку шаблон базового класса требует как минимум двух параметров шаблона.

4

Другие решения

Не ответ, но почему бы не просто …

template <int a, int... bs>
struct max : std::integral_constant<int,
(a > max<bs...>::value ? a : max<bs...>::value)> {};

template <int a>
struct max<a> : std::integral_constant<int, a> {};

…?

2

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

Ваш базовый шаблон должен соответствовать любому количеству аргументов и не иметь реализации (поскольку max<>::value не имеет смысла), и иметь один аргумент с вариацией, со всеми вашими другими классами быть специализацией этого.

#include <iostream>
#include <type_traits>

template<int... cs>
struct max;

template <int a, int b, int... cs>
struct max<a, b, cs...>: std::integral_constant<int, (a>b? max<a, cs...>::value: max<b, cs...>::value)> {};
template <int a, int b>
struct max<a, b>: std::integral_constant<int, (a>b? max<a>::value: max<b>::value)> {};
template <int a>
struct max<a>: std::integral_constant<int, a> {};

int main() {
std::cout << max<2,1,5,7>::value << std::endl;
return 0;
}
2
По вопросам рекламы [email protected]