読者です 読者をやめる 読者になる 読者になる

EMC++ Chapter5

序文

用語

ムーブセマンティクス

  • コピー演算をムーブ演算に置き換え可能にする。
  • ムーブコンストラクタ、ムーブ代入演算子はオブジェクトのムーブセマンティクスを制御する。

完全転送

  • 任意の実引数を取り、他の関数へ転送する関数テンプレートの記述を可能にする。転送先関数は完全に同じ実引数を直接受け取ったかのように動作する。

rvalue reference

  • ムーブセマンティクスと完全転送を実現するための言語機能。
  • std::move, std::foward はrvalueへのキャストである。

問題

  1. std::moveのサンプルの実装を示せ。
  2. 以下のプログラムはtextからvalueへ、ムーブとコピーのどちらが行われるか。その理由を答えよ。
class Annotation {
public:
  explicit Annotation(const std::string text) : value(std::move(text)) {}

private:
  std::string value;
};
  1. std::moveとstd::forwardの違いを答えよ。

解答

template<typename T>
decltype(auto) move(T&& param)
{
  using ReturnType = remove_reference_t<T>&&;
  return static_cast<ReturnType>(param);
}
  1. コピーされる。textはstd::moveによって、rvalueのconst std::stringにキャストされる。std::stringの実装は以下のようになっている。

class string {
public:
  ...
  string(const string& rhs);
  string(string&& rhs);
  ...
};

ムーブコンストラクタにはconstが付いていないため、textを渡すことは出来ない。 しかし、const lvalueのconst rvalueへのバインドは認められているため、textを渡すことが出来る。 その為、コピーコンストラクタが呼ばれる。

  1. std::moveは無条件でrvalueにキャストする。std::forwardは実引数がrvalueで初期化された場合のみ、rvalueにキャストする。