- РЕДАКТИРОВАТЬ - исправлено после первоначального недоразумения.
Я полагаю, что g ++ верен, а clang ++ неправильный.
Согласно стандарту C ++ 17, 17.1.11,
параметр шаблона
Пакет шаблона функции не должен сопровождаться другим параметром шаблона, если только этот шаблон
Параметр может быть выведен из списка параметров-типов (11.3.5) шаблона функции или имеет значение по умолчанию
аргумент (17.8.2).
Таким образом, параметр шаблона со значением по умолчанию должен приниматься после пакета с переменными значениями.
Проблема в том, что мы можем установить значения шаблона по умолчанию только в объявлениях функций или также в определениях функций (если они отличаются от объявлений функций)?
На самом деле, вы можете упростить вашу проблему просто с помощью
template <typename>
void foo ();
template <typename = int>
void foo ()
{ }
int main ()
{
foo();
}
принят clang ++ и отклонен g ++.
Это не совсем понятно для меня, но в 17.1.9 я прочитал
по умолчанию
Шаблон-аргумент
может быть указан в декларации шаблона.
По умолчанию
Шаблон-аргумент
не должно быть указано в
шаблон-список параметров
с определения
член шаблона класса, который появляется за пределами класса члена. По умолчанию
Шаблон-аргумент
должен
не указывается в объявлении шаблона класса друга. Если объявление шаблона функции друга указывает
дефолт
Шаблон-аргумент
эта декларация является определением и является единственной декларацией
шаблон функции в блоке перевода
Этот фрагмент явно указывает, что «аргумент шаблона по умолчанию может быть указан в объявлении шаблона». Не в «определении».
Исключите, что "аргумент шаблона по умолчанию не должен быть указан в списке параметров шаблона определения члена шаблона класса, который появляется за пределами класса члена", поэтому я изначально пришел к выводу, что шаблон универсальный Функция может указывать шаблонный аргумент по умолчанию в «определении», но эта часть о «шаблоне класса», поэтому аргумент шаблона относится к классу, а не к члену.
Как указывает сигма (спасибо!) В 17.1.10, мы можем прочитать
Набор по умолчанию
Шаблон-аргумент
s, доступный для использования, получается путем объединения аргументов по умолчанию из
все предыдущие объявления шаблона аналогичны аргументам функций по умолчанию
Опять же: "декларации" и нет "определения".
Итак, я полагаю, что clang ++ неправильный, а g ++ правильный.