当左值传递给T &&时,会发生什么?

Yue*_*ang 1 c++ templates stl rvalue-reference c++11

这是C++ Primer第5版的练习:

练习16.45:给出以下模板,解释如果我们在文字值上调用g,如42,会发生什么.如果我们在类型为int的变量上调用g?P.690

template <typename T>
void g(T&& val)
{
    std::vector<T> v;
}

int main()
{
    //g(42);

    int i;
    g(i);
}
Run Code Online (Sandbox Code Playgroud)

在打电话时42,它编译了.

打开时i,编译器抱怨了很多错误,其中一部分粘贴如下.

forming pointer to reference type 'int&'
Run Code Online (Sandbox Code Playgroud)

我的问题是

  1. 在调用字面值时,42在这种情况下,推断出什么类型T

  2. 什么时候开始i,为什么不编译?如何理解这些错误消息?

Dav*_*rcz 5

来自http://thbecker.net/articles/rvalue_references/section_08.html

其余两个rvalue引用规则中的第一个也会影响旧式左值引用.回想一下,在11 C++之前,不允许引用引用:像A &&这样的东西会导致编译错误.相比之下,C++ 11引入了以下参考折叠规则:

A& & becomes A&
A& && becomes A&
A&& & becomes A&
A&& && becomes A&&
Run Code Online (Sandbox Code Playgroud)

其次,函数模板有一个特殊的模板参数推导规则,它通过对模板参数的rvalue引用来获取参数:

template<typename T>
void foo(T&&);
Run Code Online (Sandbox Code Playgroud)

在这里,以下适用:

  • 当在类型A的左值上调用foo时,则T解析为A&,因此,通过上面的参考折叠规则,参数类型实际上变为A&.
  • 当在类型A的右值上调用foo时,则T解析为A,因此参数类型变为A &&.

所以情况1,当传递42时,你用r值调用g,所以T被解析为int因此g的参数是int&&和std :: vector是合法的.

在第二种情况下,路过我的时候,你调用一个左值克,所以T被解析成int&这样G的参数是int&std::vector<int&>合法的.

删除带向量的行,它在两种情况下都能正常工作.

  • 看看那里:http://stackoverflow.com/questions/922360/why-cant-i-make-a-vector-of-references (2认同)