【发布时间】:2019-05-29 13:44:06
【问题描述】:
考虑这个包含成员函数和成员函数模板的类模板示例,两者都命名为f,然后尝试定义和专门化成员函数模板:
template<typename T>
struct A {
void f();
template<typename U>
void f();
};
template<>
template<typename U>
void A<double>::f() { }
template<>
template<>
void A<double>::f<int>() { }
这合法吗?成员函数模板定义应该怎么写?
在f的第一个定义中,模板声明是否确保应该选择成员函数模板f而不是成员函数f,即使模板参数没有出现在类型中?我认为没有任何方法可以进一步消除歧义,因为写 ::template f()、::f<U>()、::f<>() 或它们的组合似乎无济于事。
编译结果:
- clang:在
f<int>的特化处出现堆栈跟踪崩溃 - Visual Studio:编译成功
- gcc:在
f的第一个定义处编译错误(关于正在定义的f的歧义) - EDG:编译成功
相比之下,每个编译器都接受命名空间范围内的等价物:
namespace X {
void f();
template<typename T>
void f();
}
template<typename T>
void X::f() { }
template<>
void X::f<int>() { }
【问题讨论】:
标签: c++ templates overloading language-lawyer ambiguous