(这个问题的灵感来自Nicolai Josuttis 的 CppCon 2017 演讲。)
考虑以下源文件(对于一个对象,而不是一个完整的程序):
#include <string>
class C {
std::string s_;
public:
C(std::string s) : s_(s) { };
void bar();
};
void foo() {
std::string hello { "The quick brown fox jumped over the lazy dog" };
C c { hello };
c.bar();
}
以及它在 GodBolt 上的编译结果。
即使使用-O2
(甚至使用-O3
),似乎字符串构造函数也被调用了三次。具体来说,s
被构造,仅用于构造s_
,然后被破坏。我的问题:
- 是否允许编译器简单地
s_
从 ctor 的参数构造,而不是构造s
? - 如果不是,编译器是否允许从 移动构造
s_
,s
看看后者是如何被使用的? - 如果前面的任何一个答案是“是” - 为什么 gcc 和 clang 不这样做?
- 如果
s
构造正确,编译器不能避免构造hello
,看看它没有其他用途吗?或者至少摆脱它?