考虑这段代码:
#include <iostream>
using namespace std;
struct Foo {
public:
int _a{};
Foo(int a) : _a{a}
{
std::cout << "ctor" << std::endl;
}
Foo(const Foo &)
{
std::cout << "copy" << std::endl;
}
};
int main () {
Foo a{10};
Foo b = 10;
std::cout << b._a << std::endl;
}
当我编译时
g++ -std=c++11 -fno-elide-constructors test.cpp
输出是
导演
导演
复制
0
这是我所期望的,因为Foo b = 10
, 10
隐式构造自int
, then b
是由以下内容构造的副本Foo
。此外,我的复制构造函数不执行任何操作,因此该成员_a
遗迹0
(因为它是在类中初始化的)。
但是,当我使用复制省略时
g++ -std=c++11 test.cpp
输出是
导演
导演
10
这是奇怪至少可以说。我知道这里省略了复制构造函数,但这是一个严重的副作用(成员一次初始化为 0,一次初始化为 10),因为它会影响代码路径的其余部分。
这种行为正常吗?
在特定情况下将复制省略作为优化的全部目的是允许消除复制构造的副作用。也就是说,是的,尽管复制构造函数和/或析构函数有副作用,但它仍然期望复制省略发生。
如果您不希望在某些情况下发生复制省略,则需要安排禁止它。在您的具体情况下,不可否认,抑制复制省略有点烦人,但类似这样的方法应该可以解决问题:
template <typename T>
T const& inhibit(T const& ref) {
return ref;
}
// ...
Foo b = inhibit<Foo>(10);
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)