14

こんにちは、gcc 4.7 を使用して noexcept 移動コンストラクターを持つクラス Foo を作成し、3 番目の項目を追加するときにサイズを再割り当てする必要があるように、ベクトル予約サイズを 2 に設定しました。これを行うときに、移動コンストラクターではなくコピーコンストラクターを呼び出しているようです。ここで何か不足していますか?

#include <vector>
#include <iostream>

class Foo
{
  public:
  Foo(int x) : data_(x)
  {
    std::cout << " constructing " << std::endl;
  }

  ~Foo()
  {
    std::cout << " destructing " << std::endl;
  }

  Foo& operator=(const Foo&) = default;
  Foo& operator=(Foo&&) = default;

   Foo(Foo&& other) noexcept : data_(std::move(other.data_))
   {
    std::cout << " Move constructing " << std::endl;
   }

   Foo(const Foo& other) noexcept :  data_(other.data_)
   {
    std::cout << " Copy constructing " << std::endl;
   }

  private:
  int data_;
};


int main ( int argc, char *argv[])
{
  std::vector<Foo> v;
  v.reserve(2);
  v.emplace_back(1);
  std::cout << "Added 1" << std::endl;
  v.emplace_back(2);
  std::cout << "Added 2" << std::endl;
  v.emplace_back(3);
  std::cout << "Added 3" << std::endl;
  std::cout << "v size: " << v.size() << std::endl;
}

出力:

 constructing 
Added 1
 constructing 
Added 2
 constructing 
 Copy constructing 
 Copy constructing 
 destructing 
 destructing 
Added 3
v size: 3
 destructing 
 destructing 
 destructing 
4

1 に答える 1

14

GCC 4.7 と 4.8 の両方で少しいじった後、実際には 4.7 のバグのようで、クラスのデストラクタがマークされていないnoexcept場合にのみ表示されます。

struct Foo {
  Foo() {}
  ~Foo() noexcept {}
  Foo(Foo&&) noexcept { std::cout << "move constructor" << std::endl; }
  Foo(const Foo&) noexcept { std::cout << "copy constructor" << std::endl; }
};

int main() {
  std::vector<Foo> v;
  v.reserve(2);
  v.emplace_back();
  v.emplace_back();
  v.emplace_back();
}

GCC 4.7 では次のように表示されます。

move constructor
move constructor

noexceptデストラクタから削除すると:

struct Foo {
  Foo() {}
  ~Foo() {}
  Foo(Foo&&) noexcept { std::cout << "move constructor" << std::endl; }
  Foo(const Foo&) noexcept { std::cout << "copy constructor" << std::endl; }
};

GCC 4.7 では次のように表示されます。

copy constructor
copy constructor

GCC 4.8 は、どちらの場合も move コンストラクターを使用します。

于 2013-09-06T10:49:17.693 に答える