g ++无法解决模板函数重载

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已提交;期待一个明确的答案。

mao*_*aow 1

有趣的问题。我认为您在这里遇到的是重载解析,更具体地说是模板专业化的部分排序规则

我引用:

通俗地说,“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>,它就不再可行,因此更加专业。