错误转发右值参考

Ale*_*lex 6 c++ rvalue c++11

我正在尝试新增的右值参考(在vs2012 express中).

我不明白.给出下面的代码(大部分来自c ++标准,其中解释了std :: forward).

struct A
{
    A(int& i, const float& j):
        m_i(i),
        m_j(j){}

    int& m_i;
    const float& m_j;
};

template<class T, class A1, class A2>
T* factory(A1&& a1, A2&& a2)
{
    return new T(a1, a2);
}

void test()
{

    A* a1 = factory<A>(1, 1.2f);

    //How does this work ?        
    a1->m_i = 2;
}
Run Code Online (Sandbox Code Playgroud)

我不明白m_i绑定到哪里.

我将基本上有一个左值引用到右值引用(&&&),ref refpsing规则变为(&)只是一个简单的左值引用.但是参考什么?

And*_*owl 10

我不明白m_i绑定到哪里.

m_i绑定到A构造函数的参数.A这里构造函数的论点是什么?

在这种情况下,由于factory转发其参数A(即它不使用std::forward<>()),那么什么被传递到A左值.这是因为a1命名,并且命名对象是左值.

类型a1是不相关的,以确定是否a1是一个左或右值.因此,即使a1类型为rvalue-reference to int(int&&),就像程序中的情况一样,参数a1本身也是一个命名对象,因此它是一个左值.

这意味着,因为m_i具有类型lvalue-reference to int,m_i 可以绑定(并且实际上是绑定)到factory's(lvalue)参数a1,该参数在factory()返回时将被销毁.换句话说,你留下了一个悬垂的参考.

试图取消引用它(正如你在程序中稍后所做的那样)会召唤未定义的行为.

但是,如果您的factory()函数已将其参数转发A构造函数:

template<class T, class A1, class A2>
T* factory(A1&& a1, A2&& a2)
{
    return new T(std::forward<A1>(a1), std::forward<A2>(a2));
}
Run Code Online (Sandbox Code Playgroud)

这会导致编译器错误,因为机制std::forward<>()会确保左值保持左值,并且右值保持rvalues.试图将左值引用绑定到右值是非法的,因此对A构造函数的调用将失败.