RVO和std :: vector实现

时间:2015-11-13 11:06:08

标签: c++ visual-studio gcc rvo nrvo

我编写了下面的代码来检查流行的C ++ 03编译器是否尽可能实现RVO。 (参见我关于RVO的相关问题Return value optimization: ho can I avoid copy construction of huge STL containers.)。

据我所知,简短的回答是否定的。但我不确定我理解。

我有以下五个关于clang gcc和VS9的std :: vector实现的问题, 阅读下面的代码和输出:

  1. 为什么编译器C Fun1复制两次向量?
  2. 为什么编译器B和C总是构造至少一个非请求的元素?
  3. 为什么使用编译器C Fun2将此非请求元素设置为两次?
  4. 为什么保留空间会为编译器B和C产生一个非请求的元素?
  5. 这一切都符合标准吗?
  6. 奖金问题:所有这些都符合用户的期望吗?
  7. #include <iostream>
    #include <vector>
    #include <cassert>
    
    #define SIZE (3) 
    
    class NRVO{
    public:
      NRVO() : name_(-1){}
      ~NRVO(){
        std::cout << "Destroy "<< name_ << "\n";
      }
      void set_name(){name_ = counter++;}
    private:
      int name_;
      static int counter; 
    };
    
    int NRVO::counter = 0;
    
    std::vector<NRVO> fun1(){
      std::vector<NRVO> vec(SIZE);  
      for(std::vector<NRVO>::iterator v_it = vec.begin();
          v_it != vec.end();
          ++v_it){
        v_it->set_name();
      }
      return vec;
    }
    
    void fun2(std::vector<NRVO>& vec){
      vec.clear();
      vec.resize(SIZE);  
      for(std::vector<NRVO>::iterator v_it = vec.begin();
          v_it != vec.end();
          ++v_it){
        v_it->set_name();
      }
      return;
    }
    
    int main(){
      {
        std::vector<NRVO> myNrvo1;
        std::cout << "Fun1\n";
        myNrvo1 = fun1();
        assert(myNrvo1.size()==SIZE);
      }
      {
        std::vector<NRVO> myNrvo2;
        std::cout << "Fun2\n";
        fun2(myNrvo2);
        assert(myNrvo2.size()==SIZE);
      }
      {
        std::vector<NRVO> myNrvo3;
        myNrvo3.reserve(SIZE);
        std::cout << "Fun3\n";
        fun2(myNrvo3);
        assert(myNrvo3.size()==SIZE);
      }
      return 0;
    }
    

    使用流行的C ++ 11编译器A输出

    Fun1
    Destroy 0
    Destroy 1
    Destroy 2
    Fun2
    Destroy 3
    Destroy 4
    Destroy 5
    Fun3 
    Destroy 6
    Destroy 7
    Destroy 8
    

    使用流行的C ++ 03编译器B输出

    Fun1
    Destroy -1
    Destroy 0
    Destroy 1
    Destroy 2
    Destroy 0
    Destroy 1
    Destroy 2
    Fun2
    Destroy -1
    Destroy 3
    Destroy 4
    Destroy 5
    Fun3 
    Destroy -1
    Destroy -1
    Destroy 6
    Destroy 7
    Destroy 8
    

    使用流行的C ++ 03编译器C输出

    Fun1
    Destroy -1
    Destroy 0
    Destroy 1
    Destroy 2
    Destroy 0
    Destroy 1
    Destroy 2
    Destroy 0
    Destroy 1
    Destroy 2
    Fun2
    Destroy -1
    Destroy -1
    Destroy 3
    Destroy 4
    Destroy 5
    Fun3
    Destroy -1
    Destroy -1
    Destroy -1
    Destroy 6
    Destroy 7
    Destroy 8
    

0 个答案:

没有答案