VisualStudio2012 で使った方がよいC++11の機能

# 環境
Microsoft Visual Studio Professional 2012

# 参考
[C++11の新機能のうち便利そうなものを自分用にメモる](http://qiita.com/k2ymg/items/d4405d2f000688263aab)　※この記事の抜粋になってしまった
[std::bind](http://kaworu.jpn.org/cpp/std::bind)

<!--
# 型エイリアス
使えない気がする。→使えない！

```cpp
typedef int MyNumber;
```

ではなく

```cpp
using MyNumber = int;
```

を使う。
templateも使えるので上位互換っぽい。

```cpp
template<class Value>
using MyVector = std::vector<Value>;
```
-->

# スマートポインタ
std::unique_ptr, std::shared_ptr 等が追加。
boostを使う必要なし。

```cpp
#include <memory>

class SmartPtr
{
  public:
    SmartPtr()
    {
        std::cout << "new SmartPtr" << std::endl;
    }
    ~SmartPtr()
    {
        std::cout << "delete SmartPtr" << std::endl;
    }
};

// スマートポインタ
{
    std::unique_ptr<SmartPtr> sp;
    sp.reset(new SmartPtr());    // new SmartPtr
}                                // delete SmartPtr

```

# enum class

enum名::enum項目名 みたいな使い方ができる。

```cpp
#include <cstdint> // std::uint32_t のため

enum class EnumTest : std::uint32_t
{
    Enum1 = 123,
    Enum2,
};

{
    EnumTest e = EnumTest::Enum1;
    if (e == EnumTest::Enum1)
    {
    }
} 
```

# コンテナ

std::unordered_map, std::unordered_set, std::array 等が追加。
boostを使う必要なし。

```cpp
#include <array>

{
    std::array<int, 10> ar = {};
    ar.fill(5);                  // 全ての要素を5で埋める。
    for (auto const &a : ar)     // for については後述。
    {
        std::cout << a << std::endl;   // 5/5/5/5/...
    }
}

```

# for
逆順はないみたい。
その分まだboost/foreach.hppを使う方がいいかも。

```cpp

#include <string>
#include <vector>
#include <unordered_map>

{
    // コンテナに対してイテレーションする
    std::vector<std::string> vec;
    vec.push_back("first");
    vec.push_back("second");
    for (auto const &v : vec)
    {
        std::cout << v << std::endl;                                       // first/second
    }

    // マップ
    std::unordered_map<int, std::string> map;
    map[-10] = "minus 10";
    map[ 32] = "plus  32";

    // v.first/v.second でアクセス
    for (auto const &v : map)
    {
        std::cout << "[" << v.first << "] : " << v.second << std::endl;    // [-10] : minus10/[32] : plus 32
    }
```

# std::begin, std::end
STLコンテナ以外にも使用できる。

```cpp
#include <iostream>
#include <algorithm>

{
    int arr[12] = {1,2,3,4,5,6,7,8,9,10,11,12};
    std::cout << "for : ";
    for (auto a : arr)
    {
        std::cout << a << ",";                       // for : 1,2,3,4,5,6,7,8,9,10,11,12
    }
    std::cout << std::endl;

    // std::begin/std::end
    int* p = std::find(std::begin(arr), std::end(arr), 3);
    if (p != std::end(arr))
    {
        std::cout << "find : " << *p << std::endl;   // find : 3
    }
    std::fill(std::begin(arr), std::end(arr), 256);
    std::cout << "fill : ";
    for (auto a : arr)
    {
        std::cout << a << ",";                       // fill : 256,256,...256,
    }
    std::cout << std::endl;
}
```

# nullptr

NULLではなくnullptrを使う。

# 型推論
auto や decltype で型を自動判定する。
関数でもいける。

```cpp
float getFloat()
{
    return 1.53f;
}

{
    // decltype
    decltype(getFloat()) d = getFloat();
    std::cout << "decltype(getFloat()) d is " << d << std::endl;  // decltype(getFloat()) d is 1.53

    // auto
    auto dd = d;
    const auto& myprintf = printf;
    myprintf("myprintf %f\n", dd);                                // myprintf 1.530000
}
```

# static assert
同じくboostを使わないでよくなった。

```cpp
{
    static const int test[] =
    {
        0, 1, 2, 3,
    };

    // NG
    //static_assert((sizeof(test)/sizeof(int)) == 3, "test is invalid size.");
    // OK
    static_assert((sizeof(test)/sizeof(int)) == 4, "test is invalid size.");
}

```

<!--
# コンストラクタ
メンバの初期値を指定できる。　→ できない。
他の形式のコンストラクタを呼べるようになった。　→ うそ。できない。
-->

# ラムダ式
auto と組み合わせて使いやすくなった気がする。

```cpp
{
    int z = 2;
    auto func1 = [](int x) {
        return x * x;
    };
    auto func2 = [&z](int x) {
        int ret = z*x;
        --z;
        return ret;
    };
    std::cout << "func1() = " << func1(3) << std::endl;   // func1() = 9
    std::cout << "func2() = " << func2(3) << std::endl;   // func2() = 6
    std::cout << "z       = " << z        << std::endl;   // z       = 1
}
```

# std::function, std::bind
もともとあったと思うんだけど、使いやすくなった。
boost::bind とかは使う必要なくなった。

```cpp
#include <functional>

class LumdaFunc
{
  public:
    LumdaFunc() : member(0), func() {};
    ~LumdaFunc() {};

    void make(int x)
    {
        member = x;
        auto f = [this]() {
            std::cout << "member is " << member << std::endl;
        };
        func = f;
    }
    void call()
    {
        func();
    }

  private:
    int member;
    std::function<void ()> func;
};

class BindMethod
{
  public:
    BindMethod(int m) : member(m) {};
    ~BindMethod() {};

    void bindMethod(int x)
    {
        std::cout << "bindMethod : " << member << ", and next is " << x << std::endl;
        member = x;
    }

  private:
    int member;
};

int bindFunc(int x, int y, int& z)
{
    ++z;
    std::cout << "x is " << x << ", y is " << y << std::endl;
    return z;
}

{
    LumdaFunc lf;
    lf.make(3);
    lf.call();    // member is 3

    // bind
    int opt = 32;
    auto f1 = std::bind(bindFunc, std::placeholders::_1, std::placeholders::_2, std::ref(opt));
    f1(1,2);                                                    // x is 1, y is 2
    std::cout << "after f1(1,2), opt is " << opt << std::endl;  // after f1(1,2), opt is 33

    // クラスのメソッドに bind
    BindMethod bm(512);
    auto f2 = std::bind(&BindMethod::bindMethod, bm, std::placeholders::_1);
    f2(1024);     // bindMethod : 512, and next is 1024
    f2(2048);     // bindMethod : 1024, and next is 2048
}

```


# コード全体

```cpp
#include <memory>
#include <array>
#include <functional>
#include <string>
#include <vector>
#include <unordered_map>
#include <cstdint>
#include <iostream>

namespace
{

    // スマートポインタ
    class SmartPtr
    {
      public:
        SmartPtr()
        {
            std::cout << "new SmartPtr" << std::endl;
        }
        ~SmartPtr()
        {
            std::cout << "delete SmartPtr" << std::endl;
        }
    };

    // enum class
    enum class EnumTest : std::uint32_t
    {
        Enum1 = 123,
        Enum2,
    };

    // decltype
    float getFloat()
    {
        return 1.53f;
    }

    // override
    class Base
    {
      public:
        Base() : member(0) {};
        virtual ~Base() {};

        virtual void setBase(int a)
        {
            member = a;
        }

      private:
        int member;
    };
    class Inherited : public Base
    {
      public:
        Inherited() : Base(), inherited_member(0) {};
        ~Inherited() {};

        virtual void setBase(int a) override
        {
            inherited_member = a;
        }

      private:
        int inherited_member;
    };

    // lumda/function
    class LumdaFunc
    {
      public:
        LumdaFunc() : member(0), func() {};
        ~LumdaFunc() {};

        void make(int x)
        {
            member = x;
            auto f = [this]() {
                std::cout << "member is " << member << std::endl;
            };
            func = f;
        }
        void call()
        {
            func();
        }

      private:
        int member;
        std::function<void ()> func;
    };

    // function
    class BindMethod
    {
      public:
        BindMethod(int m) : member(m) {};
        ~BindMethod() {};

        void bindMethod(int x)
        {
            std::cout << "bindMethod : " << member << ", and next is " << x << std::endl;
            member = x;
        }

      private:
        int member;
    };

    int bindFunc(int x, int y, int& z)
    {
        ++z;
        std::cout << "x is " << x << ", y is " << y << std::endl;
        return z;
    }
}


int main()
{

    // 開始
    std::cout << "cpp11 test." << std::endl;

    // スマートポインタ
    {
        std::unique_ptr<SmartPtr> sp;
        sp.reset(new SmartPtr());
    }

    // enum class
    {
        EnumTest e = EnumTest::Enum1;
        if (e == EnumTest::Enum1)
        {
            std::cout << "enum1 " << static_cast<std::uint32_t>(EnumTest::Enum1) << std::endl;
            std::cout << "enum2 " << static_cast<std::uint32_t>(EnumTest::Enum2) << std::endl;
        }
    } 

    // array
    {
        std::array<int, 10> ar = {};
        ar.fill(5);
        for (auto const &a : ar)
        {
            std::cout << a << std::endl;
        }
    }

    // for
    {
        std::vector<std::string> vec;
        vec.push_back("first");
        vec.push_back("second");
        for (auto const &v : vec)
        {
            std::cout << v << std::endl;
        }

        // マップ
        std::unordered_map<int, std::string> map;
        map[-10] = "minus 10";
        map[ 32] = "plus  32";

        for (auto const &v : map)
        {
            std::cout << "[" << v.first << "] : " << v.second << std::endl;
        }
    }

    // 型推論
    {
        // decltype
        decltype(getFloat()) d = getFloat();
        std::cout << "decltype(getFloat()) d is " << d << std::endl;

        // auto
        auto dd = d;
        const auto& myprintf = printf;
        myprintf("myprintf %f\n", dd);
    }

    // static assert
    {
        static const int test[] =
        {
            0, 1, 2, 3,
        };

        // NG
        //static_assert((sizeof(test)/sizeof(int)) == 3, "test is invalid size.");
        // OK
        static_assert((sizeof(test)/sizeof(int)) == 4, "test is invalid size.");
    }

    // lumda
    {
        int z = 2;
        auto func1 = [](int x) {
            return x * x;
        };
        auto func2 = [&z](int x) {
            int ret = z*x;
            --z;
            return ret;
        };
        std::cout << "func1() = " << func1(3) << std::endl;
        std::cout << "func2() = " << func2(3) << std::endl;
        std::cout << "z       = " << z        << std::endl;
    }

    // function
    {
        LumdaFunc lf;
        lf.make(3);
        lf.call();

        // bind
        int opt = 32;
        auto f1 = std::bind(bindFunc, std::placeholders::_1, std::placeholders::_2, std::ref(opt));
        f1(1,2);
        std::cout << "after f1(1,2), opt is " << opt << std::endl;

        // クラスのメソッドに bind
        BindMethod bm(512);
        auto f2 = std::bind(&BindMethod::bindMethod, bm, std::placeholders::_1);
        f2(1024);
        f2(2048);
    }

    // 終了
    std::cin.get();

    return 0;
}

```

出力

```
cpp11 test.
new SmartPtr
delete SmartPtr
enum1 123
enum2 124
5
5
5
5
5
5
5
5
5
5
first
second
[-10] : minus 10
[32] : plus  32
decltype(getFloat()) d is 1.53
myprintf 1.530000
func1() = 9
func2() = 6
z       = 1
member is 3
x is 1, y is 2
after f1(1,2), opt is 33
bindMethod : 512, and next is 1024
bindMethod : 1024, and next is 2048
```