moveが気になったので

魔導書Vol.1で触れられていたC++0xのmoveが気になったので,ちょっと書いてみた.

#include <iostream>

using namespace std;

struct Foo {
  int v_;
  
  Foo() : v_(0) { cout << "ctor (default) for " << this << endl; }
  Foo(int a) : v_(a) { cout << "ctor (with int) for " << this << endl; }
  Foo(const Foo &x) : v_(x.v_) { cout << "ctor (copy) for " << this << endl; }
  Foo(Foo &&x) : v_(move(x.v_)) { cout << "ctor (move) for " << this << endl; }
  ~Foo() { cout << "dtor for " << this << endl; }
  
  friend ostream &operator<<(ostream &ost, const Foo &x)
  {
    ost << x.v_ << " in " << &x;
    return ost;
  }
  
  friend Foo operator+(const Foo &a, const Foo &b)
  {
    cout << __func__ << endl;
    Foo ret;
    ret.v_ = a.v_ + b.v_;
    return ret;
  }
  
  friend Foo &&operator+(const Foo &a, Foo &&b)
  {
    cout << __func__ << " (with [l, r])"<< endl;
    b.v_ += a.v_;
    return move(b);
  }
  
  friend Foo &&operator+(Foo &&a, const Foo &b)
  {
    cout << __func__ << " (with [r, l])"<< endl;
    a.v_ += b.v_;
    return move(a);
  }
  
  friend Foo &&operator+(Foo &&a, Foo &&b)
  {
    cout << __func__ << " (with [r, r])"<< endl;
    a.v_ += b.v_;
    return move(a);
  }
};

int main()
{
  {
    Foo a(1) ,b(2), c(3), d(4), e(5);
    puts("");
    
    Foo f = a + b + c + d + e;
    cout << f << endl;
    puts("");

    Foo g = a + (b + (c + (d + e)));
    cout << g << endl;
    puts("");
    
    Foo i = (a + b) + c + (d + e);
    cout << i << endl;
    puts("");
  }
  
  return 0;
}
$ g++-mp-4.5 -std=c++0x move.cpp
$ ./a.out 
ctor (with int) for 0xbfffeb5c
ctor (with int) for 0xbfffeb58
ctor (with int) for 0xbfffeb54
ctor (with int) for 0xbfffeb50
ctor (with int) for 0xbfffeb4c

operator+
ctor (default) for 0xbfffeb60
operator+ (with [r, l])
operator+ (with [r, l])
operator+ (with [r, l])
ctor (move) for 0xbfffeb48
dtor for 0xbfffeb60
15 in 0xbfffeb48

operator+
ctor (default) for 0xbfffeb64
operator+ (with [l, r])
operator+ (with [l, r])
operator+ (with [l, r])
ctor (move) for 0xbfffeb44
dtor for 0xbfffeb64
15 in 0xbfffeb44

operator+
ctor (default) for 0xbfffeb68
operator+
ctor (default) for 0xbfffeb6c
operator+ (with [r, l])
operator+ (with [r, r])
ctor (move) for 0xbfffeb40
dtor for 0xbfffeb6c
dtor for 0xbfffeb68
15 in 0xbfffeb40

dtor for 0xbfffeb40
dtor for 0xbfffeb44
dtor for 0xbfffeb48
dtor for 0xbfffeb4c
dtor for 0xbfffeb50
dtor for 0xbfffeb54
dtor for 0xbfffeb58
dtor for 0xbfffeb5c

仕様書とその実装の全てを把握している訳ではないので何とも言えないし,Fooのメンバ変数はintだからあまり意味が無いかもしれないけど,Expression Templateの方が全体を構成した後に計算できそうな感じだなぁ…

たぶん,コンストラクタ周りでオーバーヘッドを潰すスパイス,みたいな感じで使えばいいのかな?(抽象的な表現だなぁ

追記

暗黙なムーブコンストラクタとムーブ代入演算子が導入されるそうだ.

あ,上のコードは代入演算子は定義してないや…

リンク先の定義だと,メンバ変数が実体であれポインタ(参照)であれ「移動」ではなくて「コピー」になるのか?…コメントされているような定義ではないんだなぁ.