English 中文(简体)
视像C++2010年7月2日
原标题:Copy elision on Visual C++ 2010 Beta 2
  • 时间:2009-11-07 13:19:27
  •  标签:

我读了。 Pass by Value on C++ 接下来的博客,并创建了,该方案,以便在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 << "
Move assign from RVO: " <<  
 ;
    {
        MoveableClass a;
        a = CreateRVO();
    }
    std::cout << "Move elided: " << (MoveableClass::Elided ? "Yes" : "No") <<  
 ;
    MoveableClass::Elided = true;   // reset for next test

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

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

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

这里是我以视频C++10.0(Beta 2)的释放方式汇编的产出:

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

然而,我很抱着一句话。 如你所知,除头一项行动外,所有行动都是有道理的。 为什么编审员能够用第86行的“可变目录”(std:vector)进行RVO,但能够用第97行的“可变目录”进行吗? 这是否只是与劳动和社会保障部的争 a,或者是否有充分理由? 如果有充分理由,它为什么仍然能够在第91条线上的可移动地图集上进行NRVO?

我很想知道,这样我就可以睡觉。

问题回答

感谢Dave。

I ve added my tests to that example:
pastebin.com/f7c8ca0d6

Curiously it shows that all types of elisions are not being performed except for NRVO!
Edit: Actually I suppose this is because it is the only test where the object ever has a name.

我也尝试过其他的STL类,得出同样的结果。 然而,在尝试我自己的非走私类型时,它按预期运作。 我可以认为,对可能造成这种情况的STL型号而言,什么是特别的,我不知道还有什么东西可以尝试。

I ll submit a bug report.
Edit: Submitted here

增 编

Hmm.

看来,如果你改变数据构造,

MoveableClass::MoveableClass(std::vector<double> data)

接受病媒感染,如:

MoveableClass::MoveableClass(const std::vector<double>& data) 

该公司做的是罚款。 如果你以价值通过病媒,为什么不可行?

这里还有一份版本,如果任何人想要在那里进行测试,则应汇编早期版本的“特别志愿人员”手册。 http://pastebin.com/f3bcb6ed1”rel=“nofollow noreferer” http://pastebin.com/f3b6ed1。

可是,更新和维护





相关问题
热门标签