C++11、Arduinoでどこまで使えるの?


この辺を参考にしてます。

+ [今すぐに使いたいC++11の新機能](http://minus9d.hatenablog.com/entry/20130815/1376557665)
+ [C++11, C++14 新機能まとめ ～使いそうなものだけ](http://qiita.com/leon-joel/items/81415c1ef355c6246280)
+ [C++高速化](https://heavywatal.github.io/cxx/speed.html)

現時点でArduino.appが1.8.2です。
いつのころからかC++11が使えるようになっているらしいです。
ただし、いろいろ便利なライブラリはついてないとか。

素のArduino.appでどこまで使えるのか、まあ、何か便利な機能はないかな?程度のノリですが、いろいろ試してみました。

ちなみに、いろいろなコンテナ関連、ポインタ関連の機能は、自分の理解と利用の範囲を超えるので試してません。あしからず。

#autoによる型推論 : できる。ただし、配列にはできない。

```c++:
auto x = 1.0;
auto y = 1;
```
みたいなことができます。右辺値から変数の型を推論するそうな。

ただし、配列で同じようにするとエラーに。

```c++:
auto ary[] = {0,1,2,3};
/* エラー：
sketch_may02a:3: error: 'ary' declared as array of 'auto'
 auto ary[] = {0,1,2,3};
         ^
*/
```
配列にはこれまで通り ```int ARRAY_A[] = {1,2,3,4};``` みたいな感じがいいようです。

#Range-based for loop : 使える。


``` c++:
int ary[] = {1,2,3,4};

for (auto d: ary){
	//何らかの処理
}

```
みたいなことができます。
型はautoが使いやすいが、具体的なものでも問題ありません。
コピーコストが問題になる場合は、auto&& で参照するか、変更がないのであれば const auto& が使えるようです。

添字が必要な場合は、今まで通りか、要素が少なければ

```C++:
const int RANGE[] = {0,1,2,3};

for (const auto& d: RANGE){
	//何らかの処理
}
```
みたいにするかな。

#template : 使える。ただし、STLはない。

```C++:
template<typename T>T add(T a, T b){
    return a + b;
  }
```
みたいなことができます。
ただしSTLがないので、いろいろ便利なコンテナの類は使えないようです。
#戻り値を後置で宣言 ： 使える。

```C++:
//今まで
int add(int a, int b){
	return a + b;
};
//後置で宣言
auto add(int a,int b) -> int {
	return a + b;
};
```
上下同じことになります。ラムダ式と同じ見た目。なれれば見やすい?
後置の場合、->型名 は省略できません。
autoって書いてあるけど推論してくれない...

#decltype : 使える
decltype(式)で式の型を返します。

```C++:
auto add(int a,int b) -> decltype(a + b){
	return a + b;
};
```
で、戻り値の型を推論することができます。


上の三つをまとめると

```C++:
template<typename T,typename U>auto add(T a, U b) ->decltype(a+b){
    return a + b;
  }
```
みたいなことができます。

#ラムダ式 ： 使える。ただし、関数の引数になれるが、戻り値にはなれない。

即時で使えるほか、auto変数で受けられます。

```C++:
auto addF = [](const int& a, const int& b) -> int {return a + b;};
```

関数の引数にできます。

```C++:
template<class F> int call2(F f) {
  return f(2);
}
auto f = [](int v) { return v + 3; };
auto a = call2(f);
```

ただし、ラムダ式に限らず、関数を返すことができないようです。

```C++:
auto func() {
    int x = 0;
    return [=]()mutable -> int {
        return x++;
    };
}
/*エラー：
sketch_may02a:24: error: 'func' function uses 'auto' type specifier without trailing return type
 auto func() {
           ^
*/
```
構造体で関数オブジェクトを作って同じことしてみました。ちょっと無理矢理ですが...
やっぱりエラー。

```C++:
auto Func(){
  struct {
    private:
    int i = 0;
    public:
    int operator()(){
      return i++;
    };
  } f ;
  return f;  
}
/*エラー：
sketch_may02a:39: error: cannot convert 'Func()::<anonymous struct>' to 'int' in return
   return f;  
          ^
*/
```
どちらのコードも、paiza.ioで試したらエラーは出ませんでした。

使いどころがむずかしい...
今まで通り、簡単なことは普通の関数で、複雑なことは関数オブジェクトでやると思います。
#constexpr : 使える。
constexprは、keywordとしてはハイライトされないけれど、コンパイルは普通に通るようです。

```C++:
constexpr unsigned int factorial(unsigned int x) {
    return x == 0 ? 1 : factorial(x - 1) * x;
}
```
使いどころがまだよくわかっていない...

#{}による初期化 : 使えない。

```C++:
auto b {1};
/*エラー
sketch_may02a:9: error: deducing from brace-enclosed initializer list requires #include <initializer_list>
 auto b {1};
          ^
*/
```
でもまあ、「初期化と代入は違うぞ」という気持を込めて

```C++:
auto a (1);
int ary[] {1,2,3,4};
```
みたいな書き方にしようかと思います。          

違ってるよ、とか、こんな便利な機能があるよ、というのがあればコメントおねがいします。