dvi*_*ide 6 c++ visual-c++ visual-studio-2010-beta-2 copy-elision c++11
我在读" 想要速度"?在C++ Next博客上传递Value并创建此程序以了解复制省略并在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
}
Run Code Online (Sandbox Code Playgroud)
这是我在Visual C++ 10.0(Beta 2)上以发布模式编译时得到的输出:
从RVO移动分配:
构造实例1(无数据)
构造实例2(带数据)
从移动构造实例3 2
销毁实例2
从3分配实例1
销毁实例3
销毁实例1
移动省略:否从RVO简单移动分配:
构造实例1(无数据)
构造实例2(使用简单数据)
从2分配实例1
销毁实例2
销毁实例1
移动省略:是从NRVO移动分配:
构造实例1(无数据)
构造实例2(带数据)
从2分配给实例1
销毁实例2
销毁实例1
移动省略:是从NRVO简单移动赋值:
构造实例1(无数据)
构造实例2(使用简单数据)
从2分配实例1
销毁实例2
销毁实例1
移动省略:是
但是,我有一件事感到困惑.正如你所看到的,除了第一个动作之外,所有的动作都被省略了.为什么编译器不能在第86行使用MoveableClass(std :: vector)执行RVO,但在第97行可以使用MoveableClass(int)?这只是MSVC的一个错误还是有充分的理由呢?如果有充分的理由,为什么它仍然可以在第91行的MoveableClass(std :: vector)上执行NRVO?
我想了解它,所以我可以快乐地入睡.:)
唔。
看来如果你改变数据构造函数
MoveableClass::MoveableClass(std::vector<double> data)
Run Code Online (Sandbox Code Playgroud)
通过引用接受向量,就像这样,
MoveableClass::MoveableClass(const std::vector<double>& data)
Run Code Online (Sandbox Code Playgroud)
效果很好!如果按值传递向量,为什么不起作用?
如果有人想在那里运行测试,这里还有一个应该在早期版本的 MSVC 上编译的版本。它不包含 C++0x 功能:http://pastebin.com/f3bcb6ed1
| 归档时间: |
|
| 查看次数: |
959 次 |
| 最近记录: |