Ответ 1
Я просмотрел его и обнаружил, что он указан в 14.5.2/2:
Локальный класс не должен иметь шаблонов участников. Правила доступа (раздел 11) применяются к именам шаблонов членов. Деструктор не должен быть шаблоном-членом. Нормальная (не шаблонная) функция-член с заданным именем и типом и шаблон-член-член с тем же именем, который может быть использован для создания специализации того же типа, могут быть объявлены в классе. Когда оба существуют, использование этого имени и типа относится к члену без шаблона, если не указан явный список аргументов шаблона.
И он дает пример:
template <class T> struct A {
void f(int);
template <class T2> void f(T2);
};
template <> void A<int>::f(int) { } // non-template member
template <> template <> void A<int>::f<>(int) { } // template member
int main()
{
A<char> ac;
ac.f(1); //non-template
ac.f(’c’); //template
ac.f<>(1); //template
}
Обратите внимание, что в стандартном выражении specialization
ссылается на функцию, которую вы пишете, используя явную специализацию и функцию, сгенерированную с помощью экземпляра, и в этом случае мы имеем дело с созданной специализацией. specialization
относится не только к функциям, которые вы создаете, используя явно специализированный шаблон, для которого он часто используется.
Заключение: GCC ошибается. Комо, с которым я также тестировал код, правильно его исправляет и выдает диагностику:
"ComeauTest.c"
, строка 16: ошибка:"void doh::operator()(bool)"
не является объектом, который может быть явно специализированнымtemplate<> void doh::operator()(bool i)
Обратите внимание, что он не жалуется на специализацию шаблона для int
(только для bool
), поскольку он не относится к одному и тому же имени и типу: Тип функции, который будет иметь специализация, это void(int)
, который отличается от типа функции нечастной функции-члена, которая void(bool)
.