C++11について気になった事リストと参考リンクメモ

# ことのおこり
cocos2d-xをやるにあたってc++を5年振りくらいに触ったらc++11ってのになっていて、
色々知らない言葉が出てきてナニコレうわーんってなったので
なにこれワードと参考にしたリンクとざっくりしたメモを並べておく。
メモね。動作確認とかしてないです。
結局書きかけ。。。

間違ってたら教えて下さい。

# なにこれ…
* rvalue reference 
* std::move
* std::forward
* NRVO/RVO
* emplace (mapとかvectorとか)
* std::piecewise_construct
* std::forward_as_tuple
* lambda

 
意外と少ないかも

# 参照関連

## rvalue reference
とりあえず、lvalueとrvalueというものがあって、rvalueは一時的なオブジェクトのこと。

以前から `&` を使うことで参照を作ることはできたけど、それはlvalue reference、つまり
左辺値参照でしかなかった。

もし、参照が右辺値であること、つまりもう使わないよってことをを明示できたら、
わざわざ値をコピーしなくても良いってことを明示できるので、
中身をポインタの挿げ替えとか出来て、パフォーマンス向上できるよね。

ということで、`&&`を使うことで明示的に右辺値を参照することができるようになった。

これによって、例えば

```cpp

class A {
private:
char *p;
public:
  A() {
    this->p = new char[ //...
  }
  A(A&& r)
  {
    // ここでrはもう使われないことがわかっているので、
    // r内部のpはコピーしないで良い
    this->p = r.p;
    r.p = nullptr;
  }
}

```

とか効率的なコンストラクタを提供したりできる。
moveコンストラクタと言うらしい。

それから通常のコピーコンストラクタをprivateにしてしまえば、
コストの掛かるコピーをしようとしていることをコンパイラに
指摘させることができるんじゃないかな、多分。

## std::move

rvalue -> lvalueはできないが、 lvalue -> rvalueは可能。
キャストすることができる。キャストすることで、オブジェクトをもう使わないと
明示することができる。
それを便利にしてくれるのが `std::move`ということだ。

上記の例だと、

```cpp

A a;
A aa(std::move(a));

```

とすることで、`A(A&& r)`のmoveコンストラクタが呼び出される(多分)。

* [本の虫:rvalue reference 完全解説](http://cpplover.blogspot.jp/2009/11/rvalue-reference_23.html)
* [C++0x 右辺値参照 std::move - Faith and Brave - C++で遊ぼう](http://faithandbrave.hateblo.jp/entry/20080304/1204628281)
* [C++0x の右辺値参照がこんなに難しいわけがない。 - C++でゲームプログラミング](http://d.hatena.ne.jp/osyo-manga/20101117/1289958984)
* [C++0x - 右辺値参照(Rvalue reference) / ムーブ・セマンティクス(Move semantics) - Faith and Brave - C++で遊ぼう](http://faithandbrave.hateblo.jp/entry/20071004/1191497817)
* [本当は怖くないムーブセマンティクス - yohhoyの日記（別館）](http://yohhoy.hatenablog.jp/entry/2012/12/15/120839)
* [C++0x 標準ライブラリ完全解説　～ No.02 std::move, &amp;lt;utility&amp;gt; - 野良C++erの雑記帳](http://d.hatena.ne.jp/gintenlabo/20110116/1295195945)

## std::forward

`&&`を使えば、もう使わないことを明示できるぜ、という話だったのだけど、
テンプレートの場合

```cpp
template < typename T >
void f( T && t ) {}
````

```cpp
int a = 3;
f(a); // lvalue
f(5); // rvalue
```
どっちもコンパイルが通ってしまう。

これは通らないと通らないで引数が増えたときにオーバーロードしなきゃならない
数が爆発的に増えて大変そうなのだけど、

```cpp
template < typename T >
void f( T && t ) {
  A(std::move(t)); //rvalueなんだからmoveしたい
}
````
ときに困るということだ。テンプレートの場合はrvalueなのかlvalueなのか
分からない。万一lvalueのときに内部でmoveされると、

```cpp
f(A()); //問題ない
A a;
f(a);
// えっ、知らないうちにmoveされちゃってる？
```
ということが起きかねない。

そこで`std::forward`ですよ。

```cpp
template < typename T >
void f( T && t ) {
 A(std::forward<T>(t));
}
```
`std::forward`は、このときTがlvalueならlvalue, rvalueならrvalue
として渡してくれる。


## NRVO/RVO

(Named )Return Value Optimization
だそうだ。
コンパイラが不要なコンストラクタ呼び出し部分を省いてくれるそうな。

* [C++0x における NRVO - 野良C++erの雑記帳](http://d.hatena.ne.jp/gintenlabo/20110125/1295991902)
* [暗黙のmoveとNRVO - joynote break;](http://d.hatena.ne.jp/joynote/20110822/1314012953)
* [NRVO(RVO)とMove Semantics - 神様なんて信じない僕らのために](http://isoparametric.net/entry/20091219/1261192152)

## emplace

vectorに`emplace_back`というメソッドが…
mapにもemplaceが。

これは、vectorとかmapへの追加のときに、無駄にコピーが発生していたよね、ということで。

```cpp
struct A {
  A(char, int, const std::string&);
};

std::vector<A> a_vec;
a_vec.push_back(A('a', 1, "foo"));
```
とやっていて、これはAをつくって、それがコピーされてa_vecに入っていた。

これを、直接内部で生成することができる感じです。
emplace_backの場合はコンストラクタ引数を直接渡します。

```cpp
a_vec.emplace_back('a', 1, "foo");
```
あとはmoveコンストラクタがあれば

```cpp
a_vec.emplace_back(std::move(A{'a', 1, "foo"});
```
としても、コストを抑えられるのではないかと思います。

* [C++0x Placement Insert(配置挿入) - Faith and Brave - C++で遊ぼう](http://faithandbrave.hateblo.jp/entry/20080930/1222768173)

### piecewise_construct

こいつに関しては、まず pairとかtupleのコンストラクタに関係が。

* [std::pair::pair - cppreference.com](http://ja.cppreference.com/w/cpp/utility/pair/pair)

ここを見てみると書いてあるけど、つまり、
第１引数が`std::piecewise_construct`だったら、
第2, 第3引数に、pairのfirst, secondに入るオブジェクトの
コンストラクタ引数をtupleで渡しますよ、
という目印の模様。

* [たぶんら • std::piecewise_construct](http://0x35.tumblr.com/post/17101221358/std-piecewise-construct)

こんな感じ。

### forward_as_tuple

例えばemplaceするときに、

```cpp
m.emplace(piecewise_construct, tuple1, tuple2);
// tuple1は tuple<A, B, C>(a, b, c)とか
```

でkey/valueのコンストラクタ引数を渡せるけれど、
このtupleもmoveで一発でいかないものかと。

そこで`forward_as_tuple`を使うと

```cpp
m.emplace(piecewise_construct, 
	forward_as_tuple(a, b, c),
	forward_as_tuple(d, e, f));
```

「tupleとして(forwardして)渡す」ができて、
幸せになれる、ということかと。


* [std::forward_as_tuple - cppreference.com](http://en.cppreference.com/w/cpp/utility/tuple/forward_as_tuple)
* [「や」の字: forward_as_tuple() からの復元](http://yak-ex.blogspot.jp/2011/12/forwardastuple.html)