如何解决C++ 只调用一个构造函数
我正在尝试理解右值引用。 这是我到目前为止编写的代码:
class A {
public:
A(const char* str) {
std::cout << str;
}
A(A&& other) {
std::cout << "other";
}
};
int main() {
A m(A(A(A("hello"))));
}
输出只有"hello"
,这让我很困惑。
由于A("hello")
是传递给第二个构造函数的临时对象,但是代码输出好像只调用了第一个构造函数。
我猜这要么是编译器优化,要么我错过了一些关于构造函数和右值的细节。
解决方法
您观察到的也称为 copy elision,更准确地说:
在以下情况下,编译器需要省略类对象的复制和移动构造,即使复制/移动构造函数和析构函数具有可观察到的副作用。对象被直接构建到存储中,否则它们将被复制/移动到那里。复制/移动构造函数不需要存在或可访问:
(...)
- 在对象的初始化中,当初始化表达式是一个与变量类型相同的类类型(忽略cv限定)的纯右值时:
T x = T(T(f())); // 只调用一次 T 的默认构造函数,初始化 x
这正是您的情况。
请注意,从 C++17 开始,优化是强制的。它对于 C++11 来说是可选的,但您的编译器似乎无论如何都会应用它。
,是的,这是一个编译器/语言(见后者)优化。
可以是seen here,这将输出:
hello
在编译器选项中将标准从 -std=c++2a
更改为 -std=c++14
仍然只会给您 hello
,但除了标准更改之外,如果您还添加:
-fno-elide-constructors
的选项,您应该看到您所希望的。
但是,如果您将 C++17 或 C++2a 指定为标准,则此选项将不再有效,因为在某些情况下此省略已成为强制性标准,因为这些标准,您的情况就是其中之一。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。