2013年4月21日日曜日

RVOと右辺値参照

C++11のお話。

RVO(Return Value Optimization)と右辺値参照が競合する場合は、
RVOが優先される。

#include <iostream>
class test
{
public:
  test(void) : val(0)
  {
    std::cout << "ctor with no args" << std::endl;
  }
  ~test(void)
  {
    std::cout << "dtor : " << val << std::endl;
  }
  test(int a) : val(a)
  {
    std::cout << "ctor : " << a << std::endl;
  }
  test(const test &) = delete; // undef copy constructor
  test(test &&a) : val(a.val)
  {
    std::cout << "move ctor : " << val << std::endl;
    a.val = -val;
  }
  const test& operator=(test &&a)
  {
    std::cout << "move oper= " << a.val << std::endl;
    val = a.val;
    a.val = -val;
    return *this;
  }
  
private:
  int val;
};

test ret_test(int a)
{
  test t(a);
  return t;
}

int main(void)
{
  {
    test t1 = ret_test(1); // RVO
    t1 = ret_test(2); // rvalue reference
  }
  std::cout << "---" << std::endl;
  {
    test t3 = std::move(ret_test(3)); // rvalue reference by std::move
  }
  return 0;
}



処理した結果は次のようになる。g++ ver.4.7.2 と Debian clang version 3.0-6.2
のどちらでも同じ結果となった。

ctor : 1
ctor : 2
move oper= 2
dtor : -2
dtor : 2
---
ctor : 3
move ctor : 3
dtor : -3
dtor : 3