以下是 C ++ Primer 5th Edition 的练习:
练习16.45:给出以下模板,解释如果发生了什么 我们称g为字面值,例如42.如果我们将g称为a int类型的变量? P.690
template <typename T>
void g(T&& val)
{
std::vector<T> v;
}
int main()
{
//g(42);
int i;
g(i);
}
在呼叫42
时,它已编译。
当在i
时,编译器抱怨了很多错误,其中一部分粘贴如下。
forming pointer to reference type 'int&'
我的问题是
在这种情况下调用字面值42
时,T
的推断类型是什么?
在i
时,为什么不编译?如何理解这些错误消息?
答案 0 :(得分:5)
来自http://thbecker.net/articles/rvalue_references/section_08.html
其余两个rvalue引用规则中的第一个也会影响旧式左值引用。回想一下,在11 C ++之前,不允许引用引用:类似于A&amp; A; &安培;会导致编译错误。相比之下,C ++ 11引入了以下参考折叠规则:
A& & becomes A&
A& && becomes A&
A&& & becomes A&
A&& && becomes A&&
其次,函数模板有一个特殊的模板参数推导规则,它通过对模板参数的右值引用来获取参数:
template<typename T>
void foo(T&&);
以下适用:
所以情况1,当传递42时,你用r值调用g,所以T被解析为int
因此g的参数是int&&
而std :: vector是合法的。
在案例2中,当传递i时,您使用左值调用g,因此T被解析为int&
因此g的参数为int&
而std::vector<int&>
为 NOT < / strong>合法。
删除带向量的行,它在两种情况下都能正常工作。