为什么下面的模板函数重载分辨率不明确
Why is the following template function overload resolution ambiguous?
根据我对C++部分排序算法的理解,似乎第一个严格来说是第二个定义的子集。因此,只要两者都可以选择,就应该首选第一个。但是我收到以下错误消息:
p_o.cpp:13:10: error: call to 'f' is ambiguous
return f<R>(args...);
^~~~
p_o.cpp:17:12: note: in instantiation of function template specialization 'f<int, double, int>' requested here
auto a = f<int>(0.3, 1);
^
p_o.cpp:7:3: note: candidate function [with T = int, Ts = <>]
T f(T a, Ts ...args) {
^
p_o.cpp:12:3: note: candidate function [with R = int, T = int, Ts = <>]
R f(T a, Ts ...args) {
^
1 error generated.
有人可以解释一下我哪里出错了吗?我是元编程的新手。
#include <tuple>
using namespace std;
template <typename T, typename ...Ts>
T f(T a, Ts ...args) {
return a;
}
template <typename R, typename T, typename ...Ts>
R f(T a, Ts ...args) {
return f<R>(args...);
}
int main() {
auto a = f<int>(0.3, 1);
static_assert(is_same<int, decltype(a)>::value);
}
您可以将违规案例归结为以下内容:
f<int>(1);
这可以解释为对以下的调用:
R f<R, T, Ts...>(T, Ts...) // with `R = int`, `T=int` and `Ts = <>`
或致电:
T f<T, Ts>(T, Ts...) // with `T = int` and `Ts = <>`
请注意,部分模板排序的更专业推理适用于参数类型,在这里,它们都是相同的,因此,2 个重载被认为对您的调用同样有效,从而导致歧义。
要解决这个问题,您需要一些东西来取消两个重载之一的资格。您似乎想提取与请求类型匹配的包的第一个成员......为此,您可以使用基于 SFINAE 的设计:
template< typename R, typename T, typename... Ts >
std::enable_if_t< std::is_same< R, T >::value, R > f( T a, Ts... )
{
return a;
}
template< typename R, typename T, typename... Ts >
std::enable_if_t< ! std::is_same< R, T >::value, R > f( T, Ts... args )
{
return f< R >( args... );
}
相关文章:
- 为什么使用SFINAE而不是函数重载
- 为什么我不能在 C++ 中的特定函数重载中调用同一函数的任何其他重载?
- c++:可变模板和函数重载
- 在缺少函数重载时抛出异常,并带有 std::variant 而不是编译时错误
- 解决模板成员函数重载
- 为什么不允许成员函数和非成员函数之间的函数重载?
- 推断模板化函数中的函数重载
- C++复制函数重载导致"must be a nonstatic member function"错误
- 为什么 std::sort 找不到合适的(静态成员)函数重载?
- 可变参数泛型 lambda 和函数重载
- C++中的函数重载和继承
- 当有右值构造函数可用时,为什么从右值调用类引用构造函数重载?
- C/C++ 可变参数宏函数重载
- 将基类的成员函数重载到其他派生类C++
- C++ 函数重载匹配
- C++函数重载,具体步骤是什么
- C++:使用 param pack 显式调用函数重载
- 隐式生成的函数重载用于右值参数?
- 使用函数重载输入运算符
- 运算符重载函数上的函数重载