0
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&& f(...); 而不是 some_return_type f(...); ?

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

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

4

2 回答 2

6

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

可怕的练习。与左值引用一样,您正在做的是返回对本地对象的引用。当调用者收到引用时,被引用的对象已经消失了。

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

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

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

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

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

那是追加还是替换向量?

并使调用者代码更简单:

auto read_input();

对比

std::vector<int> v; 
read_input(v);
于 2012-05-05T16:07:34.280 回答
0

f_2您阻止编译器应用NRVO 时。当您放弃演员表并启用优化进行编译时,您会发现它同样有效。绝对不需要强制转换参考,这在f_2.

于 2014-03-06T14:53:14.723 回答