gpt4 book ai didi

c++ - Visual C++ 2010 Beta 2 上的复制省略

转载 作者:塔克拉玛干 更新时间:2023-11-02 23:42:14 27 4
gpt4 key购买 nike

我正在阅读 Want Speed? Pass by ValueC++ Next blog 上并创建了 this program感受 C++0x 中的复制省略和移动语义:

#include <vector>
#include <iostream>

class MoveableClass {
public:
MoveableClass() : m_simpleData(0), instance(++Instances) {
std::cout << "Construct instance " << instance << " (no data)" << std::endl;
}

MoveableClass(std::vector<double> data) : m_data(std::move(data)), m_simpleData(0), instance(++Instances) {
std::cout << "Construct instance " << instance << " (with data)" << std::endl;
}

MoveableClass(int simpleData) : m_simpleData(simpleData), instance(++Instances) {
std::cout << "Construct instance " << instance << " (with simple data)" << std::endl;
}

MoveableClass(const MoveableClass& other)
: m_data(other.m_data), m_simpleData(other.m_simpleData), instance(++Instances)
{
std::cout << "Construct instance " << instance << " from a copy of " << other.instance << std::endl;
Elided = false;
}

MoveableClass(MoveableClass&& other)
: m_data(std::move(other.m_data)), m_simpleData(other.m_simpleData), instance(++Instances)
{
std::cout << "Construct instance " << instance << " from a move of " << other.instance << std::endl;
Elided = false;
}

MoveableClass& operator=(MoveableClass other) {
std::cout << "Assign to instance " << instance << " from " << other.instance << std::endl;
other.Swap(*this);
return *this;
}

~MoveableClass() {
std::cout << "Destroy instance " << instance << std::endl;
--Instances;
}

void Swap(MoveableClass& other) {
std::swap(m_data, other.m_data);
std::swap(m_simpleData, other.m_simpleData);
}

static int Instances;
static bool Elided;

private:
int instance;
int m_simpleData;
std::vector<double> m_data;
};

int MoveableClass::Instances = 0;
bool MoveableClass::Elided = true;

std::vector<double> BunchOfData() {
return std::vector<double>(9999999);
}

int SimpleData() {
return 9999999;
}

MoveableClass CreateRVO() {
return MoveableClass(BunchOfData());
}

MoveableClass CreateNRVO() {
MoveableClass named(BunchOfData());
return named;
}

MoveableClass CreateRVO_Simple() {
return MoveableClass(SimpleData());
}

MoveableClass CreateNRVO_Simple() {
MoveableClass named(SimpleData());
return named;
}

int main(int argc, char* argv[]) {
std::cout << "\nMove assign from RVO: " << '\n';
{
MoveableClass a;
a = CreateRVO();
}
std::cout << "Move elided: " << (MoveableClass::Elided ? "Yes" : "No") << '\n';
MoveableClass::Elided = true; // reset for next test

std::cout << "\nMove assign from RVO simple: " << '\n';
{
MoveableClass a;
a = CreateRVO_Simple();
}
std::cout << "Move elided: " << (MoveableClass::Elided ? "Yes" : "No") << '\n';
MoveableClass::Elided = true; // reset for next test

std::cout << "\nMove assign from NRVO: " << '\n';
{
MoveableClass a;
a = CreateNRVO();
}
std::cout << "Move elided: " << (MoveableClass::Elided ? "Yes" : "No") << '\n';
MoveableClass::Elided = true; // reset for next test

std::cout << "\nMove assign from NRVO simple: " << std::endl;
{
MoveableClass a;
a = CreateNRVO_Simple();
}
std::cout << "Move elided: " << (MoveableClass::Elided ? "Yes" : "No") << '\n';
MoveableClass::Elided = true; // reset for next test
}

这是我在 Visual C++ 10.0 (Beta 2) 上以 Release模式编译时得到的输出:

Move assign from RVO:
Construct instance 1 (no data)
Construct instance 2 (with data)
Construct instance 3 from a move of 2
Destroy instance 2
Assign to instance 1 from 3
Destroy instance 3
Destroy instance 1
Move elided: No

Move assign from RVO simple:
Construct instance 1 (no data)
Construct instance 2 (with simple data)
Assign to instance 1 from 2
Destroy instance 2
Destroy instance 1
Move elided: Yes

Move assign from NRVO:
Construct instance 1 (no data)
Construct instance 2 (with data)
Assign to instance 1 from 2
Destroy instance 2
Destroy instance 1
Move elided: Yes

Move assign from NRVO simple:
Construct instance 1 (no data)
Construct instance 2 (with simple data)
Assign to instance 1 from 2
Destroy instance 2
Destroy instance 1
Move elided: Yes

然而,我对一件事感到困惑。如您所见,除了第一个 Action 外,所有的 Action 都被省略了。为什么编译器不能在第 86 行使用 MoveableClass(std::vector) 执行 RVO,但可以在第 97 行使用 MoveableClass(int)?这只是 MSVC 的错误还是有充分的理由?如果有充分的理由,为什么它仍然可以在第 91 行对 MoveableClass(std::vector) 执行 NRVO?

我想了解它,这样我就可以高枕无忧了。 :)

最佳答案

感谢您回复戴夫。

我已将我的测试添加到该示例中:
pastebin.com/f7c8ca0d6

奇怪的是,它表明除了 NRVO 之外,没有执行所有类型的省略!
编辑:实际上我想这是因为这是唯一一个对象曾经有名字的测试。

我也尝试了其他STL类型,得到了同样的结果。但是,当尝试我自己的非 pod 类型时,它按预期工作。我想不出可能导致这种情况的 STL 类型有什么特别之处,所以我不知道还能尝试什么。

我会提交错误报告。
编辑:Submitted here

谢谢

关于c++ - Visual C++ 2010 Beta 2 上的复制省略,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1693005/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com