【问题标题】:Copy constructor vs. return value optimization复制构造函数与返回值优化
【发布时间】:2009-03-20 11:54:08
【问题描述】:

previous question 中,一个普通的按值返回函数似乎总是将其return 参数复制到从它分配的变量中。

这是标准要求的,还是可以通过在函数体内构造“分配给”变量来优化函数?

struct C { int i; double d; };

C f( int i, int d ) {
    return C(i,d); // construct _and_ copy-construct?
}

int main() {
    C c = f( 1, 2 ); 
}

【问题讨论】:

    标签: c++ copy-constructor return-value-optimization


    【解决方案1】:

    该标准允许此处任何级别的复制省略:

    • 构造一个本地临时,将其复制构造为返回值,并将返回值复制构造到本地“c”中。
    • 构造一个本地临时文件,并将其复制构造到“c”中。
    • 用参数“i,d”构造“c”

    【讨论】:

    • 能否提供标准中的章节号?
    • 尼尔发布的相同:12.15。你有不同的理解吗?
    【解决方案2】:

    标准规定不需要使用复制构造函数 - 请参阅第 12.8/15 节:

    15 每当临时类对象 使用复制构造函数复制, 这个对象和副本有 相同的 cv 非限定类型,一个 实施允许对待 原件和复印件两份 不同的引用方式 相同的对象,而不是在 全部,即使类副本 构造函数或析构函数有边 效果。

    还有更多类似的东西。

    【讨论】:

    • 我 1998 年标准中的 12.5 是“免费商店”,您指的是其他标准吗?
    【解决方案3】:

    不通过引用传递参数并将结果分配给它?

    【讨论】:

    • 因为它在呼叫站点更丑陋且不太灵活。它应该只在性能关键的地方进行。
    • 或者当你需要多个返回值(例如一个状态和一个值)时
    【解决方案4】:

    有一种非常简单且很好的方法可以完全避免此类考虑 - 您可以考虑将 boost::shared_ptr 返回到创建的对象 - 在可用性方面实际上是相同的,但您的对象肯定不会被不必要地复制- 如果你通过几层函数调用返回它,它也将是真的。

    【讨论】:

    • shared_ptr std::string or std::pair or std::vector 不好。
    • 为了避免复制构造,我可以使用堆 i.s.o。堆栈存储。我知道 :)/ 但我想知道我是否可以信任编译器,即 保证 调用我的复制构造函数的标准。我做不到。
    • 好奇:为什么你还需要这个保证 xtof?
    • @Mykola - 为什么你认为它不好?正是这种返回值,可以很好的将结果share_ptr,避免在从一些内部方法返回时复制一个巨大的向量或一个长字符串。
    • @Iraimbilanja:当“其他”问题的答案说复制构造函数将始终在返回时被调用时,我想到了这个问题。我对此表示怀疑。我的问题有点修辞,我必须承认:)。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-05-24
    • 1970-01-01
    • 2016-10-01
    • 2012-08-07
    相关资源
    最近更新 更多