okn*_*vin 6 c++ gcc language-lawyer variadic-templates c++11
使用以下代码,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
}
Run Code Online (Sandbox Code Playgroud)
与:
<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
^
...
Run Code Online (Sandbox Code Playgroud)
可在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中的错误?
编辑:谢谢大家,您的反馈意见对我有所帮助。仅供参考,错误90642已提交;期待一个明确的答案。
有趣的问题。我认为您在这里遇到的是重载解析,更具体地说是模板专业化的部分排序规则
我引用:
通俗地说,“A 比 B 更专业”意味着“A 接受的类型比 B 少”。
我认为 clang 的编译是正确的,结果应该采用第二个候选者
template <typename X = int, typename T, typename ...R>
inline void func(const S<T>& t, R... p) {}
Run Code Online (Sandbox Code Playgroud)
因为如果第一个参数不是类型S<T>,它就不再可行,因此更加专业。