复制构造函数 vs 返回值优化

8
之前的问题中,似乎一个普通的按值返回函数总是将其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 ); 
}
4个回答

8

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

  • 构建本地临时变量,将其复制构造到返回值中,并将返回值复制构造到本地变量"c"中。或者
  • 构建本地临时变量,并将其复制构造到"c"中。或者
  • 使用参数"i,d"构建"c"

请问您能提供标准中的章节号吗? - Mykola Golubyev
尼尔发布的内容是一样的:12.15。你有不同的理解吗? - Iraimbilanja

7
标准规定不一定需要使用复制构造函数-请参见第12.8/15节:
“每当使用复制构造函数复制临时类对象,并且此对象和副本具有相同的cv非限定类型时,实现允许将原始对象和副本视为两种不同的引用方式,而根本不执行复制,即使类复制构造函数或析构函数具有副作用。”
还有很多类似的内容。

我的1998标准中的12.5是“自由存储器”,您是否指的是其他标准? - Mykola Golubyev

0

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


因为它在调用时更加丑陋和不灵活。应该只在性能关键的地方使用。 - Iraimbilanja
或者当你需要多个返回值(例如状态和值)时 - xtofl

-1

有一种非常简单而好的方法可以完全避免这种考虑 - 您可以考虑返回一个 boost::shared_ptr 到创建的对象 - 当涉及到可用性时,它几乎是相同的,但您的对象肯定不会被不必要地复制 - 如果您通过几层函数调用返回它,这也是正确的。


不建议使用 shared_ptr 来管理 std::string、std::pair 或 std::vector。 - Mykola Golubyev
为了避免复制构造,我可以使用堆而不是栈存储。我知道:)/但我想知道是否可以信任编译器即标准来“保证”调用我的复制构造函数。但事实并非如此。 - xtofl
好奇问一下:xtof,你为什么需要这个保证呢? - Iraimbilanja
@Mykola - 你为什么认为这不好?正是这种返回值,使用share_ptr来共享结果可能非常好,避免从一些内部方法返回时复制大量向量或长字符串。 - RnR
@Iraimbilanja:当“其他”问题的答案说返回时始终会调用复制构造函数时,我产生了这个问题。我对此表示怀疑。我必须承认我的问题有点修辞。 :) - xtofl

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接