使用以下代码,g ++失败:
template <typename X = int, typename T, typename ...R>
inline void func(const T&, R...) {}
template <typename T>
struct S {};
template <typename X = int, typename T, typename ...R>
inline void func(const S<T>&, R...) {}
int main() {
func(42);
func(S<int>()); // OK
func(S<int>(), 1); // NOK
func<int>(S<int>(), 1); // NOK
}
具有:
<source>: In function 'int main()':
<source>:13:21: error: call of overloaded 'func(S<int>, int)' is ambiguous
func(S<int>(), 1); // NOK
^
<source>:13:21: note: candidates are:
<source>:2:17: note: void func(const T&, R ...) [with X = int; T = S<int>; R = {int}]
inline void func(const T&, R...) {}
^
<source>:8:17: note: void func(const S<T>&, R ...) [with X = int; T = int; R = {int}]
inline void func(const S<T>&, R...) {}
^
<source>:14:26: error: call of overloaded 'func(S<int>, int)' is ambiguous
func<int>(S<int>(), 1); // NOK
^
...
可通过gcc v4.8.1和v9.1复制。使用clang(v3.0.0和v8.0.0),icc(v13.0.1和v19.0.1),msvc(v19.14和v19.20)进行编译。
代码有效还是gcc中的错误?
编辑:谢谢大家,您的反馈意见对我有所帮助。仅供参考,bug 90642已提交;期待一个明确的答案。
答案 0 :(得分:1)
有趣的问题。我认为您遇到的是overload resolution,更具体地说是partial ordering rules for template specialization
我引用:
非正式地,“ A比B更专业”表示“ A接受的类型少于B”。
我认为用clang编译是正确的,重新解决应该使用第二个候选对象
template <typename X = int, typename T, typename ...R>
inline void func(const S<T>& t, R... p) {}
由于第一个参数的类型不是S<T>
,因此它不再可行,因此更加专业化。