Я изучаю вариативный шаблон С++ 11 и создал структуру шаблона для вычисления максимального числа заданного списка и пробовал:
#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;
}
но g++ жалуется:
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). — примечание в конце]
Так что я думаю, что любой частично специализированный шаблон, который не отличается от базового/первичного, считается ошибкой, хотя иногда мы можем генерировать некоторые неспециализированные формы выражения из обычных.