【问题标题】:Is it a bad idea to return an object by value that contains a member vector?按包含成员向量的值返回对象是不是一个坏主意?
【发布时间】:2016-09-09 14:58:44
【问题描述】:

短版:

如果我的对象包含一个 std::vector,那么对于按值返回该对象和按值返回向量是否适用相同的经验法则?

C++11 中的这种变化,我理解“保证”按值返回向量是否很快?

加长版:

我有一个包含 std::vector 的小型包装类。

class gf255_poly
{
    public:

        // ... Lots of polynomial methods

    protected:
        std::vector<unsigned char> p;
};

我想从某些函数返回此类的实例,例如:

// Performs polynomial addition in GF(2^8). 
gf255_poly gf255_poly_add(const gf255_poly &poly1, const gf255_poly &poly2) const
{
    // Initialize:
    gf255_poly dst = poly1;

    // Add all coefficients of poly1 to poly2, respecting degree (the usual polynomial addition)
    for (int deg = 0; deg <= poly2.degree(); deg++)
        dst.addAt(deg, poly2.coef(deg));

    return dst;
}

我在how to return a member vectorwhether it is still a bad design pattern 上找到了大量信息来返回std::vector(在大多数情况下这似乎没问题)。不过,我还没有找到很多包含较大对象成员的向量。

同样的建议是否适用?我是否需要在我的复制构造函数中做一些特别的事情来帮助确保返回值优化?

对于不同版本的 C++ 标准,这个问题的答案是否不同?

【问题讨论】:

  • 如果您想确定,为您的 gf255_poly 编写移动构造函数会有所帮助。
  • @appleapple:NRVO 可以忽略移动构造函数。
  • 这真的取决于返回值被返回到什么。如果它是一个已经创建的项目,那么您有一个复制/移动分配。如果它是一个新对象,那么很可能 NRVO 会启动。
  • 只是一点 - 有时您可能会过度“手动优化”,以至于您实际上无助于使代码运行得更快。编译器的优化器是为识别代码中的某些模式而构建的,如果你阻止编译器的优化器,你可以使代码运行得比它应该运行的慢。只需以最易于理解的方式编写代码,然后在检测到程序中的特定位置运行缓慢时进行分析(优化版本)。
  • @Bathsheba 我认为“确保性能”,因此忽略移动构造函数(并使用 RVO)在这里不是问题。

标签: c++ visual-studio-2008 stdvector rvo


【解决方案1】:

您在gf255_poly dst = poly1; 后面写的return dst; 正在利用命名返回值优化 (NRVO)。

这是一项比返回值优化更新的创新,但它肯定是由现代编译器实现的,而不管它们所针对的 C++ 标准是什么。绝对清楚,NRVO 不是特定于 C++11 的东西。

利用 NRVO不是一个糟糕的设计选择,因为使用它可以使源代码更易于阅读和维护。

【讨论】:

    【解决方案2】:
    • >= c++11,即使编译器无法(或不能)执行 RVO,您也可以使用移动语义来保持代码运行速度。

    你需要在你的类中有(可能是默认的)移动构造函数来启用这个行为。

    您也可以在移动构造函数上使用=default。(但Visual Studio 2008 似乎没有此功能)

    【讨论】:

      【解决方案3】:

      这取决于你的编译器有多聪明(通常很多)。因此,无论您使用什么现代编译器,它都应该是“安全的”。

      【讨论】:

        猜你喜欢
        • 2010-10-07
        • 1970-01-01
        • 2012-10-15
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2014-07-03
        • 1970-01-01
        • 2022-01-01
        相关资源
        最近更新 更多