以 rvaule 引用作为参数的函数模板重载不起作用?

function template overload with rvaule reference as argument does not work?

当输入不是右值时,以&& 为参数的函数模板似乎无法重载。以 here 为例:

template<typename A, typename B>
void test_tp_func(A&& a, B&& b)
{
    std::cout<<"tp1(" << a << "," << b << ")\n";
}
template<typename A>
void test_tp_func(A&& a, int&& b)
{
    std::cout<<"tp2(" << a << "," << b << ")\n";
}
int main()
{
    test_tp_func(1, 2);
    int i{10};
    const int& ir = i;
    test_tp_func(2, ir);
    test_tp_func(2, std::move(i));
}

输出为:

tp2(1,2)
tp1(2,10)
tp2(2,10)

我们可以看到 test_tp_func(2, ir); 根本没有使用重载。我怎样才能确保它使用 test_tp_func(A&& a, int&& b)?一种方法是在 B 为 int 时添加 enable_if_t 以禁用原始模板。但是,原始模板 test_tp_func(A&& a, B&& b) 定义在一个不受我控制的文件中。

更新示例以实际使用 const&

如何选择右值重载?如果参数是 rvaluei 不是。

它不是一个纯右值(它是一个命名变量)也不是一个亡值。

如果你只是想拦截B = int的情况,为什么不把参数类型设为int呢?使用 int&& 只会根据定义匹配右值。

如评论中所述,您不能简单地将转发引用 B&& 替换为右值引用 int&&(或任何其他具体类型代替 int),因为转发引用在参数推导过程中得到特殊处理(参见 here 并搜索“转发引用”,这是一种特殊情况)。

您需要两个重载:常量引用 const int& 和右值引用 int&&,以涵盖与原始转发引用相同的情况。