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

atk*_*ins 14 c++ constructor temporary language-lawyer

在下面的代码中,pSs.pS保证在最终的线相等?换句话说,在声明中S s = S();,我可以确定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;
}
Run Code Online (Sandbox Code Playgroud)

在每个编译器中我都测试了这个pS == s.pS,但是我对标准不够熟悉,以至于能够确保这是有保证的.

Bar*_*rry 16

没有

编译器没有义务进行复制省略.标准只是指定,[class.copy]:

当满足某些条件时,允许实现省略类对象的复制/移动构造[...]

我可以通过禁用复制省略-fno-elide-constructors,然后两个指针肯定会有所不同.例如:

$g++ -std=c++11 -Wall -pedantic -fno-elide-constructors -Wall -Wextra main.cpp && ./a.out
0x7fff5a598920 0x7fff5a598930
Run Code Online (Sandbox Code Playgroud)

在一般情况下,如果我们添加S(S&& ) = delete,那么上面的代码甚至不会编译.

  • @Mordachai:什么是C++ 13? (6认同)
  • @Mordachai不要担心这个绝对不是"最佳实践"! (2认同)

vso*_*tco 11

大多数编译器执行所谓的复制/移动省略,这是由C++标准指定的.但它不能保证.例如,您可以使用-fno-elide-constructorsgcc 进行编译,您将看到所有构造函数的所有荣耀.

Live example on Coliru


vla*_*don 5

无法保证不会有临时性.但三巨头编译器将优化它(即使使用-O0开关).

为了保证没有临时性,只需写:

int main()
{
  // ...
  S s{};
  // ...
}
Run Code Online (Sandbox Code Playgroud)

或者干脆S s;.