我正在尝试模板和转发。写了一些令我惊讶的简单实验代码。我想更好地理解这种机制,可能我在这里缺乏一些知识,因此我寻求帮助。你能解释一下为什么下面代码中的两个调用都不能编译(PLACE 2和3)吗?
#include <iostream>
#include <memory>
#include <utility>
using namespace std;
void h2rvalref(int&& i) { cout << "h2rvalref" << endl; }
void h2ref(int& i) { cout << "h2ref" << endl; }
void h2val(int i) { cout << "h2val" << endl; }
template <class T, class X>
void h1(T&& t, X x) { x(forward<T>(t)); }
int main()
{
// PLACE (1)
h1<int, decltype(h2rvalref)>(1, h2rvalref);
auto b = 1;
// PLACE (2)
// h1<int, decltype(h2ref)>(b, h2ref); // --> ERROR - no matching function..., cannot convert 'b' (type 'int') to type 'int&&'
// PLACE (3)
// h1<int, decltype(h2val)>(b, h2val); // --> ERROR - no matching function..., cannot convert 'b' (type 'int') to type 'int&&'
}
我不明白为什么错误说明将int转换为int&amp;&amp;当我有int类型的值b。
答案 0 :(得分:1)
问题是您要为函数提供显式模板参数。当您明确提供要转发的类型的模板参数时,转发参数不起作用(除非您确实知道自己在做什么)。
template <class T, class X> void h1(T&& t, X x) { x(forward<T>(t)); }
当你写h1<int, decltype(h2ref)>
时,你得到一个这样的函数:
void h1(int&& t, decltype(h2ref) x) { x(forward<int>(t)); }
int&&
是与int
不同的类型,不能绑定到int
类型的左值,例如您传入的b
;它只能绑定到int
如果你不使用模板参数,它就可以了:
h1(b, h2ref);
这将实例化一个如下所示的函数:
void h1(int& t, // int& && collapses to just int&
decltype(h2ref) x) {
x(forward<int&>(t));
}