具有自动功能的模板函数的重载分辨率
overload resolution of template function with auto
以下 3 个重载
template <class T> auto foo() { return 1; }
template <class T> int foo() { return 2; }
template <class T> T foo() { return 3; }
以下是否形成不良?
static_cast<int(*)()>(&foo<int>)();
Clang选择重载#2,而gcc无法编译(演示)
删除重载 #1 时,双方都同意选择重载 #2(演示)。
删除重载 #2 时,gcc 选择重载 #1 并且 clang 无法编译(演示)
根据 [over.over]/2,我们执行模板参数推导。这将对所有三个重载成功:在第一个重载中,记住 [temp.deduct.funcaddr]/2:
函数模板的返回类型中的占位符类型 (7.1.7.4) 是非推导上下文。如果模板 参数推导成功 对于这样的函数,返回类型由 函数体。
由于推导将成功(假设所有模板参数都显式提供了参数),因此返回类型推导为int
。在第二种情况下,由于提供了参数,因此演绎成功,在第三种情况下,将推导出T
。†
继续讨论第4段,
如果选择了多个函数,[...] 函数模板专用化
F1
如果集合包含 第二个函数模板专用化,其函数模板为 比F1
的函数模板更专业 14.5.6.2 的部分排序规则。在此种冲销之后,如有的话,应只剩下一个选定的职能。
根据 [temp.deduct.partial]/3,函数模板的函数类型用于部分排序。我们可以立即看到 #1 和 #2 的函数类型不包含任何参与演绎的模板参数,因此通过核心问题 1391 的决议引入的 [temp.deduct.partial]/4 的添加,它们的相应P
s 不用于确定排序。@bogdan在这里解释了为什么该决议有问题;底线是排序只会产生 #1 和 #2 的歧义。
也就是说,根据当前(可能有缺陷)的措辞,转换在所有情况下都是格式不正确的。如果非因/推导参数对的部分排序是固定的,
情况 1 和- 3 不明确,因为对于两个非依赖函数类型(#1 和 #2 的函数类型),没有排序对。
- 案例 2 中的接受行为是正确的(如预期的那样)。
†[temp.deduct.type]/8 element 9 (T()
),以防您好奇。
- 为什么使用SFINAE而不是函数重载
- 为什么我不能在 C++ 中的特定函数重载中调用同一函数的任何其他重载?
- c++:可变模板和函数重载
- 在缺少函数重载时抛出异常,并带有 std::variant 而不是编译时错误
- 解决模板成员函数重载
- 为什么不允许成员函数和非成员函数之间的函数重载?
- 推断模板化函数中的函数重载
- C++复制函数重载导致"must be a nonstatic member function"错误
- 为什么 std::sort 找不到合适的(静态成员)函数重载?
- 可变参数泛型 lambda 和函数重载
- C++中的函数重载和继承
- 当有右值构造函数可用时,为什么从右值调用类引用构造函数重载?
- C/C++ 可变参数宏函数重载
- 将基类的成员函数重载到其他派生类C++
- C++ 函数重载匹配
- C++函数重载,具体步骤是什么
- C++:使用 param pack 显式调用函数重载
- 隐式生成的函数重载用于右值参数?
- 使用函数重载输入运算符
- 运算符重载函数上的函数重载