C++ 返回std::vector时未调用复制构造函数
我想知道这里发生了什么:C++ 返回std::vector时未调用复制构造函数,c++,c++11,stdvector,C++,C++11,Stdvector,我想知道这里发生了什么: class Test { public: Test() { std::cout << "Constructor" << std::endl; } Test(const Test &) { std::cout << "Copy" << std::endl; } Test(const Test &&) { std::cout << "Move" << st
class Test {
public:
Test() { std::cout << "Constructor" << std::endl; }
Test(const Test &) { std::cout << "Copy" << std::endl; }
Test(const Test &&) { std::cout << "Move" << std::endl; }
~Test() { std::cout << "Destructor" << std::endl; }
};
std::vector<Test> getTestVektor() {
std::vector<Test> TestVektor(1);
return TestVektor;
}
Test getTest() {
Test TestVariable;
return TestVariable;
}
int main() {
{
std::vector<Test> TestVektor = getTestVektor();
}
std::cout << std::endl;
{
Test TestVarible = getTest();
}
std::cout << std::endl;
{
std::vector<Test> TestVektor(1);
std::vector<Test> TestVektor2 = TestVektor;
}
return 0;
}
人们可以用省略来解释第一个案例。但这与第二种情况相反,在第二种情况下调用了move构造函数
另一种解释是,函数中的std::vector释放其内容并将其传递给第二个std::vector,因此不需要调用复制构造函数。但第三个案例表明,事实并非如此
那么,这里发生了什么?或者这只是一个混乱的编译器优化?第一种情况(最坏情况下)移动向量(因此只传输内部指针,而不复制/移动Test
)
第三种情况是复制vector,您必须执行以下操作来移动它,而不是复制:
{
std::vector<Test> TestVektor(1);
std::vector<Test> TestVektor2 = std::move(TestVektor);
}
{
std::向量TestVektor(1);
std::vector TestVektor 2=std::move(TestVektor);
}
人们可以用省略来解释第一个案例
TestVektor
是根据从getTestVektor
返回的临时向量构建的。一个、两个或两个举措都可能被忽略
但这与第二种情况相反,在第二种情况下调用了move构造函数
复制/移动省略不是强制性的。它既可以用于从getTest
返回,也可以用于TestVarible
的复制初始化,但没有用于其中一个
我测试的GCC和Clang版本都省略了这两个版本
另一种解释是,函数中的std::vector释放其内容并将其传递给第二个std::vector
这正是std::vector
的move构造函数所做的
但第三种情况是复制赋值,而不是移动构造
总之,这里发生的事情主要是由
std::vector的move构造函数解释的,但第二种情况也显示了复制/移动省略的明显(缺乏)副作用。
Constructor
Destructor
Constructor
Destructor
Constructor
Copy
Destructor
Destructor
为什么VisualStudio会在案例2中调用移动对我来说是个谜。您是否禁用了优化?熟悉“命名返回值优化”?(我同意它也适用于案例2)您的复制/移动分配操作员在哪里?@BenVoigt Yes。显然,向量的移动构造函数是重要的一点…@xaxxon似乎我的编译器隐式声明了它们…@xaxxon它被更改为/O2并得到了相同的结果;-)
Constructor
Destructor
Constructor
Destructor
Constructor
Copy
Destructor
Destructor