将函数声明为BigStruct && foo(...)是一种好习惯吗?

xml*_*lmx 0 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();
}
Run Code Online (Sandbox Code Playgroud)

输出是:

f_1:
A()
~A()
f_2:
A()
A(A&&)
~A()
~A()
Run Code Online (Sandbox Code Playgroud)

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

所以,我的问题是:

我们是否应该将函数声明为some_return_type && f(...); 而不是some_return_type f(...); ?

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

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

Dav*_*eas 6

将函数声明为BigStruct && foo(...)是一种好习惯吗?

可怕的做法.与左值引用一样,您正在执行的操作是返回对本地对象的引用.当调用者接收到引用时,引用的对象已经消失.

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

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

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

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

void read_input( std::vector<int>& );
Run Code Online (Sandbox Code Playgroud)

这是附加还是替换向量?

并使调用者代码更简单:

auto read_input();
Run Code Online (Sandbox Code Playgroud)

std::vector<int> v; 
read_input(v);
Run Code Online (Sandbox Code Playgroud)