在C++11中,按值传递是一种合理的默认吗?

内容来源于 Stack Overflow,并遵循CC BY-SA 3.0许可协议进行翻译与使用

  • 回答 (2)
  • 关注 (0)
  • 查看 (54)

在传统的C ++中,将值传递给函数和方法对于大型对象来说是很慢的,并且通常会被忽视。相反,C ++程序员倾向于传递引用,速度更快,但是引入了围绕所有权的各种复杂问题,尤其是围绕内存管理(如果对象是堆分配的)

现在,在C ++ 11中,我们有Rvalue引用和移动构造函数,这意味着可以实现一个大对象(比如an std::vector),这个对象可以很便宜地将值传入和传出函数。

那么,这是否意味着缺省值应该是为类型的实例传递值,例如std::vectorstd::string?自定义对象怎么样?什么是新的最佳做法?

提问于
用户回答回答于

指南:不要复制你的函数参数。相反,按值传递它们并让编译器进行复制。

在代码中,这意味着不要这样做:

void foo(T const& t)
{
    auto copy = t;
    // ...
}

但是这样做:

void foo(T t)
{
    // ...
}

其优点是呼叫者可以foo像这样使用:

T lval;
foo(lval); // copy from lvalue
foo(T {}); // (potential) move from prvalue
foo(std::move(lval)); // (potential) move from xvalue

只做最少的工作。你需要两个重载做同样与引用,void foo(T const&);void foo(T&&);

考虑到这一点,我现在写下了我的重要构造函数:

class T {
    U u;
    V v;
public:
    T(U u, V v)
        : u(std::move(u))
        , v(std::move(v))
    {}
};

否则,通过引用const仍然是合理的。

用户回答回答于

在几乎所有情况下,你的语义应该是:

bar(foo f); // want to obtain a copy of f
bar(const foo& f); // want to read f
bar(foo& f); // want to modify f

所有其他签名只应该谨慎使用,并且有充分的理由。编译器现在几乎总是以最有效的方式解决这些问题。

扫码关注云+社区