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

时间:2019-05-25 08:32:13

标签: c++ c++11 gcc language-lawyer variadic-templates

使用以下代码,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已提交;期待一个明确的答案。

1 个答案:

答案 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>,因此它不再可行,因此更加专业化。