Ответ 1
ОРИГИНАЛЬНЫЙ ОТВЕТ: (не удаляется, так как может содержать полезную информацию)
Я бы сказал, все это сводится к тому, что перегруженный оператор шаблон считается перегруженным оператором или нет. Логически, я бы хотел подумать, что это не так, и Клэн ошибается: я считаю, что шаблон должен быть сначала выбран в качестве кандидата для разрешения перегрузки на основе совместимости имен и подписи, а затем создан, затем (возможно) выбран. Как я вижу это, только после создания экземпляра компилятор должен проверить, имеет ли в результате функция правильное количество аргументов или нет.
Но это только мое мнение. Per § 13.5.7/1 о перегрузке постфикса operator ++
:
"Если функция является функцией-членом с одним параметром (который должен иметь тип int) или не-членной функцией с двумя параметрами (второй из которых должен иметь тип int) он определяет оператор приращения postfix ++ для объектов такого типа"
Стандарт, похоже, не уточняет, следует ли рассматривать функцию шаблон как функцию, что касается ограничений на сигнатуру перегрузки законных операторов (по крайней мере, Я не мог найти ни одного предложения, которое бы разрешало эту двусмысленность). Пока это верно, на этот вопрос вряд ли можно дать четкий ответ, и у нас остались мнения.
Но я хотел бы упомянуть еще один важный аспект вопроса: согласованность.
Хотя верно, что код в тексте вопроса не компилируется на Clang, выполняется следующее:
template<typename... Ts>
int operator + (X x1, Ts... args)
{
return 0;
}
Я не вижу никакой концептуальной разницы между этими двумя случаями: если сигнатура перегрузки оператора должна быть проверена до создания экземпляра, то указанное выше определение также не должно компилироваться. Если это не так, тогда код в тексте вопроса должен компилироваться.
Итак, ответ на мой взгляд заключается в том, что либо GCC прав, либо они оба ошибаются.
UPDATE:
Как @JesseGood и @SethCarnegie правильно указывают, на 14.7/4:
"Специализация - это класс, функция или член класса, который либо создан, либо явно специализирован".
Кроме того, на 14.6/8:
"Диаграмма не должна выдаваться для шаблона, для которого может быть создана действительная специализация".
Таким образом, кажется, что Clang действительно ошибочен и не возникает ошибка компиляции для шаблона операторской функции в тексте вопроса.