简体   繁体   English

在S s = S()中,是否保证不会创建临时值?

[英]In S s = S() is it guaranteed that no temporary will be created?

In the following code, are pS and s.pS guaranteed to be equal in the final line? 在下面的代码中, pSs.pS在最后一行中是否保证相等? In other words, in the statement S s = S(); 换句话说,在声明S s = S(); , can I be sure that a temporary S will not be constructed? ,我可以确定不会构建临时S吗?

#include <iostream>
using namespace std;

struct S
{
  S() { pS = this; }
  S* pS;
};

int main()
{
  S s = S();
  S* pS = &s;
  cout << pS << " " << s.pS << endl;
}

In every compiler I've tested this in pS == s.pS , but I'm not sufficiently familiar with the standard to be able to satisfy myself that this is guaranteed. 在每个编译器中,我都在pS == s.pS对此进行了测试,但我对标准不够熟悉,以确保能够保证这一点。

NO 没有

The compiler isn't obligated to do copy elision. 编译器没有义务进行复制省略。 The standard simply specifies that, [class.copy]: 标准只是指定,[class.copy]:

When certain criteria are met, an implementation is allowed to omit the copy/move construction of a class object [...] 当满足某些条件时, 允许实现省略类对象的复制/移动构造[...]

I can disable copy elision via -fno-elide-constructors , and then the two pointers will definitely be different. 我可以通过-fno-elide-constructors elide -fno-elide-constructors禁用copy elision,然后两个指针肯定会有所不同。 For example: 例如:

$g++ -std=c++11 -Wall -pedantic -fno-elide-constructors -Wall -Wextra main.cpp && ./a.out
0x7fff5a598920 0x7fff5a598930

And in the general case, if we add S(S&& ) = delete , then the above code wouldn't even compile. 在一般情况下,如果我们添加S(S&& ) = delete ,那么上面的代码甚至都不会编译。

Most compilers performs what's called copy/move elision , which is specified by the C++ standard. 大多数编译器执行所谓的复制/移动省略 ,这是由C ++标准指定的。 But it is not guaranteed. 但它不能保证。 For example, you can compile with -fno-elide-constructors in gcc and you'll see all constructors in all their glory. 例如,您可以在gcc中使用-fno-elide-constructors进行编译,您将看到所有构造函数的所有荣耀。

Live example on Coliru Coliru的实例

There is no guarantee that there will be no temporary. 无法保证不会有临时性。 But the Big Three compilers will optimize it out (even with the -O0 switch). 但三巨头编译器将优化它(即使使用-O0开关)。

To guarantee no temporary at all just write: 为了保证没有临时性,只需写:

int main()
{
  // ...
  S s{};
  // ...
}

Or simply S s; 或者只是S s; .

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM