将一个函数声明为BigStruct&& amp;是一个很好的做法。富(...);

时间:2012-05-05 16:00:20

标签: c++ rvalue

class A
{
public:
    A()
    {
        cout << "A()" << endl;
    }

    A(const A&)
    {
        cout << "A(const A&)" << endl;
    }

    A(A&&)
    {
        cout << "A(A&&)" << endl;
    }

    A& operator=(const A&)
    {
        cout << "A(const A&)" << endl;
    }

    A& operator=(A&&)
    {
        cout << "A(const A&&)" << endl;
    }

    ~A()
    {
        cout << "~A()" << endl;
    }
};

A&& f_1()
{
    A a;
    return static_cast<A&&>(a);
}

A f_2()
{
    A a;
    return static_cast<A&&>(a);
}

int main()
{
    cout << "f_1:" << endl;
    f_1();
    cout << "f_2:" << endl;
    f_2();
}

输出是:

f_1:
A()
~A()
f_2:
A()
A(A&&)
~A()
~A()

示例代码显然表明f_1()比f_2()更有效。

所以,我的问题是:

我们是否应该始终将某个函数声明为some_return_type&amp;&amp; F(...);而不是some_return_type f(...); ?

如果我的问题的答案是真的,那么接下来是另一个问题:

有许多函数被声明为some_return_type f(...);在C ++世界中,我们应该将它们改变为现代形式吗?

2 个答案:

答案 0 :(得分:6)

  

将一个函数声明为BigStruct&amp;&amp; FOO(...);

可怕的做法。与 lvalue-references 一样,您正在做的是将引用返回给本地对象。当调用者收到引用时,引用的对象已经消失。

  

有许多函数被声明为some_return_type f(...);在C ++世界中,我们应该将它们改变为现代形式吗?

现代形式是它们已经构建的形式(仅考虑返回类型)。标准被更改为使公共表单更有效,而不是让每个人都重写所有代码。

现在有非现代版本,例如当void f( type& t ) 创建对象时type f()而不是f。那些我们想要更改为现代形式type f()的那些,因为它提供了一个更简单的界面来推理和提供更简单的用户代码:

用户无需考虑对象是已修改还是已创建

void read_input( std::vector<int>& );

是否附加或替换了矢量?

使调用者代码更简单:

auto read_input();

VS

std::vector<int> v; 
read_input(v);

答案 1 :(得分:0)

f_2中,您阻止编译器应用NRVO。当您放弃强制转换并在启用优化的情况下进行编译时,您会发现它同样有效。绝对不需要演员参考,在f_2中没有任何意义。

相关问题