c++ - g++ 无法解析模板函数重载

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

最佳答案

有趣的问题。我想你在这里遇到的是 overload resolution ,更具体地说 partial ordering rules for template specialization

我引用:

Informally "A is more specialized than B" means "A accepts fewer types than B".

我认为 clang 编译它是正确的,结果应该采用第二个候选

template <typename X = int, typename T, typename ...R>
    inline void func(const S<T>& t, R... p) {}

因为如果第一个参数不是 S<T> 类型,它不再可行,因此更加专业。

关于c++ - g++ 无法解析模板函数重载,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56303163/

相关文章:

c - Fortran/Mac OS X 中 ISO_C_binding "c_intptr_t"返回的值不正确

c++ - 需要知道如何检查输入的字符串是否已在 C++ 中的线程安全记录器内终止

c++ - 检查 bitset 中的多个位

c++ - C++中结构数组的初始化

c++ - GCC STL 是线程安全的吗?

c++ - 没有优化的 g++ 4.9 上静态 constexpr 的 undefined reference

c++ - 当数据存在时 mq_receive 返回 EAGAIN

c++ - 有一个很好的字符串表示

c++ - 如何通过引用传递 vector 的静态 vector ?

c++ - Boost.test找不到main