У меня есть следующая структура с вариативным конструктором с аргументом по умолчанию:
struct S {
template<typename... Args>
S(int n=0, Args&& ...args) {}
};
int main() {
S s1; // fine on clang and g++ (S(0) by default argument, empty Args)
S s2(1); // fine on clang and g++ (S(1), empty Args)
S s3(1, 2); // fine on g++ (S(1, 2), non-empty Args), clang complains (see below)
}
Как указано, S(1, 2) отлично компилируется на g++ (версия 7.3, протестирована с флагами -std=c++1z и -std=c++14), но clang (версия 6.0.0, протестирована с теми же флагами) сообщает мне следующее:
<source>:3:26: error: missing default argument on parameter 'args'
S(int n=0, Args&& ...args) {}
^
<source>:9:7: note: in instantiation of function template specialization 'S::S<int>' requested here
S s3(1, 2); // fine on g++ (S(1, 2), non-empty Args), clang complains (see below)
^
Я уже нашел Можно ли использовать аргументы функции пакета параметров по умолчанию?, который решает аналогичную проблему, но охватывает только случай, когда список параметров полностью пуст (например, S s()). Меня особенно интересует корпус S(1, 2).
стандарт говорит:
In a given function declaration, each parameter subsequent to a parameter with a default argument shall have a default argument supplied in this or a previous declaration or shall be a function parameter pack.
Поэтому я подумал, что мой конструктор для S действителен и значения для n и args можно вывести во всех трех случаях. Какой компилятор (если есть) правильный?
@Barry Я думаю, что другой вопрос касается пустого списка параметров, но меня особенно интересует случай S(1, 2).
@phimuemue Другой вопрос касается концепции наличия завершающего пакета параметров функции после аргумента по умолчанию ... фактический вызов несущественен. Ваш код полностью правильный, и связанный вопрос содержит отчеты об ошибках.
@Barry Спасибо за ответ. Вы правы: в отчете об ошибке (bugs.llvm.org/show_bug.cgi?id=23029#c3) есть что-то похожее на мой пример.





Компилируется нормально в MSVC 15.6.2. Возможно, Clang считывает созданную функцию как
S(int n = 0, int deduced) {}и каким-то образом не видит ее как пакет параметров, считая ее недействительной, поскольку следующий аргумент не имеет значения по умолчанию.