Visual C++で使えるC++11

  • 17,186 views
Uploaded on

身内向けですがせっかく作ったので。 …

身内向けですがせっかく作ったので。
土日に深夜のテンションで作ったので抜け漏れ誤字脱字だらけだと思います…

  • Full Name Full Name Comment goes here.
    Are you sure you want to
    Your message goes here
    Be the first to comment
No Downloads

Views

Total Views
17,186
On Slideshare
0
From Embeds
0
Number of Embeds
3

Actions

Shares
Downloads
102
Comments
0
Likes
37

Embeds 0

No embeds

Report content

Flagged as inappropriate Flag as inappropriate
Flag as inappropriate

Select your reason for flagging this presentation as inappropriate.

Cancel
    No notes for slide

Transcript

  • 1. nekko1119
  • 2.  身内向けです。  Visual C++で使えるC++11の機能を、言語機能、 ライブラリに分けて紹介します。  紹介する機能は私が独断と偏見で選んだ一部です。 全て紹介するわけではありません。  コンパイラやライブラリのバグや部分対応までい くと作業量大変なのでそこら辺は触れません  内容の正しさには気をつけていますが間違えてい る可能性もあります。
  • 3.  サンプルコードは暗黙に必要なヘッダのインク ルード、using namespace std;をしています。  また、イメージとしてのサンプルで、実際には動 かないコードもあります。  ライブラリの初出は所属する名前空間がstd::tr1 ではなくstdになった初めてのバージョンとしま す
  • 4. Visual C++ 10.0 (Visual Studio 2010) VC10 Visual C++ 11.0 (Visual Studio 2012) VC11 Visual C++ 11.0 Community Technology Preview (Visual Studio 2012) VC11CTP Visual C++ 12.0 Preview (Visual Studio 2013 Preview) VC12PR Visual C++ 12.0 (Visual Studio 2013) VC12 Visual C++ 12.0 Community Technology Preview (Visual Studio 2013) VC12CTP
  • 5.  2013年8月時点での細心のバージョンはVC12PR です。  それ以降のバージョン(VC12, VC12CTP)は公式で 公開されている開発の予定です
  • 6.  変数の型を右辺式より推論する  修飾子はつかない  C/C++03までの自動変数を表すautoと互換性が なくなった template <class F, class G, class T> void call(const F& f, const G& g, const T& t) { const auto& temp = f(t); g(temp); } int main() { auto f = [](int n){return n * n;}; auto g = [](int n){return n + n;}; cout << call(f, g, 10) << endl; }
  • 7.  ヌルポインタを表すリテラル  NULLはマクロで0に置換され、数値と曖昧となる 場合がある void func(int){} void func(int*){} int main() { func(10); func(nullptr); }
  • 8.  戻り値を宣言の後ろに記述できる  後述のdecltypeと合わせるとより便利 //int型を返す関数の宣言 int hoge(); auto foo() -> int; //void (int)型の関数ポインタを返す関数の宣言 void (*f())(int); auto g() -> void (*)(int);
  • 9.  式から型を推論する template <class T, class U> auto plus(const T& t, const U& u) -> decltype(t + u) { return t + u; } int main() { vector<double> v; v.push_back(plus(10, 10.0)); const decltype(v) u = v; }
  • 10.  コンパイル時にassertチェックが出来る  コンパイル時にチェックできるのは型とコンパイ ル時定数の2つ int main() { static_assert(sizeof(long) >= 8, "64bit以上環境が必要です"); static_assert(_MCV_VER >= 1600, "VC++10.0以上のVC++コンパイラ でなければなりません"); }
  • 11.  従来の参照は正確には左辺値参照  右辺値への参照ができるようになった  機能としてはこれだけだが、本質は別にある。今 回は機能紹介が目的なので省略 int main() { int a = 10; int& lval_ref = a; //int& ng = 10; int&& rval_ref = 10; //int&& ng = a; const int& clval_ref1 = a; const int& clval_ref2 = 10; }
  • 12.  その場に無名の一時関数オブジェクトを生成する  戻り値の省略可能  変数のコピーキャプチャ、参照キャプチャ可能 int main() { vector<int> v = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10}; vector<int> result; int border = 5; copy_if(v.begin(), v.end(), back_inserter(result), [&border](int it) { return it > border; }); }
  • 13.  enumの前方宣言が可能になった  要素の整数型を指定できるようになった  要素の最後にカンマが付いても良くなった enum weekend : unsigned short; void disp_weekend(weekend w); enum weekend : unsigned short { SATURDAY, SUNDAY, }; void disp_weekend(weekend w) { if(w == SATURDAY) { cout << "SATURDAY" << endl; } else { cout << "SUNDAY" << endl; } } int main() { dips_weekend(SATURDAY); }
  • 14.  enumにスコープができた  暗黙の型変換を禁止する enum class traffic_light : unsigned int { RED, YELLOW, BLUE }; int main() { traffic_light tl = traffic_light::RED; unsigned int i = static_cast<unsigned int>(tl); }
  • 15.  従来のfor文は強いて言うならインデックスfor文 と言える  範囲ならば何でも、範囲全体を反復処理する int main() { for (const auto& it : {1, 2, 3, 4, 5, 6, 7, 8, 9, 10}) { if(it % 5 == 0) { cout << "buzzn"; } else if (it % 3 == 0) { cout << "fizzn"; } else { cout << it << endl; } } }
  • 16.  クラス、または仮想関数にfinal指定ができる  クラスに指定した場合、そのクラスを基底クラス にすることができなくなる  仮想関数に指定した場合、その仮想関数をオー ラーライドできなくなる class hoge final {}; class foo : hoge {}; //エラー class base { virtual void func() final {} }; class derived : base { virtual void func() {}//エラー };
  • 17.  オーバーライドの意図を明確にするためにできた  タイポやオーバーライドのつもりになっているミ ス(気づきにくい)をエラーとして検出できる class hoge { virtual void func1() const {} virtual void func2() const {} void func3() {} }; class foo : hoge { virtual void fumc1() const override {} //エラー virtual void func2() override {} //エラー virtual void func3() override {} //エラー };
  • 18.  引数が1つのコンストラクタは以前から暗黙な型 変換を抑制するexplicit指定ができた  型変換演算子にもexplicit指定ができるように なったclass integer { public: explicit integer(int in) : value_(in) {} explicit operator int() const {return value_;} private: int value_; }; int main() { integer n(42); int m = static_cast<int>(n); }
  • 19.  今まではクラステンプレートにはデフォルトテン プレート引数が指定できたが、関数では無理だっ た(オーバーロードで同様のことが実現できるた め)が、できるようになった template <class T, class D = default_delete<T>> unique_ptr<T, D> make_unique(T* p, D d = D()) { return {p, forward<D>(d)}; }
  • 20.  コンストラクタから同クラスの他のコンストラク タを呼び出すことが可能になる  処理を1ヶ所に纏められる class point_xy { public: point_xy() : point_xy(0, 0) {} point_xy(int x, int y) : x_(x), y_(y) {} private: int x_; int y_; };
  • 21.  今まで引数無しコンストラクタ構文での初期化は 関数宣言とみなされたり、初期化リストは配列型 やPOD型にしか適用できなかった。それらの制限 を無くし統一された初期化構文(初期化リスト構文 の拡張)で初期化できるようになった int main() { string str1{"Hello"}; string str2 = {"World"}; string str3{}; stirng str4 = {}; pair<int, int> p1{10, 20}; pair<int, int> p2 = {10, 20}; }
  • 22.  任意の型の引数を任意個取ることができるクラス /関数テンプレートを作ることができる。  Cの可変長引数と比べて型安全である void print(){} template <class T, class... Args> void print(const T& t, Args&&... args) { cout << typeid(T).name() << "t:t" << t << endl; print(args...);} int main () { print("hoge", 42, 'c', 3.14, true); }
  • 23.  初期化リストに専用の型が出来た。これを引数に とるコンストラクタを定義することでユーザー定 義型でも初期化リストが使えるようになった。 int sum(initializer_list<int> li) { return accumulate(li.begin(), li.end(), 0); } template <class T, class U> pair<T, U> create_pair(T t, U u) { return {t, u}; //どちらかと言うと統一された初期化構文 } int main() { auto result = sum({9, 8, 7, 6}); auto p = create_pair("hello", 3.14); vector<double> v = {1.0, 2.0, 3.0}; }
  • 24.  非静的データメンバを宣言と同時に初期化出来る  C#などでは普通にできる  コンストラクタで初期化すると上書きされる class person { public: person(const string& name, int age) : name_(name), age_(age) {} int age() const {return age_;} const string& name() const {return name_;} private: string name_ = "noname"; int age = -1; }; int main() { person p; assert(p.age() == -1); person p2{"tom", 20}; assert(p.name() == "tom"); }
  • 25.  コンパイラによって自動生成される関数が既定の 動作であることを明示する class hoge { public: hoge() = default; hoge(const hoge&) = default; ~hoge() = default; hoge& operator=(const hoge&) = default; //VC12の時点でmove ctor/assignは自動生成されない };
  • 26.  望まない型変換や関数テンプレートのインスタン ス化を抑止できる  自動生成される関数の生成を抑止できる template <class T> void f(){} //char型だけはダメ template <> void f<char>() = delete; //long longより小さい型はダメ void g(long long){} void g(long) = delete; class hoge { public: hoge(const hoge&) = delete; hoge& operator=(const hoge&) = delete; //newで割り当てられないようにする void* operator new(size_t) = delete; };
  • 27.  typedefは型にしか別名をつけられない  テンプレートに対する別名をusingを用いた構文 で可能にした  usingを用いた構文で型にも別名を付けられる int add(int, int){} int sub(int, int){} template <class T> using my_vector = vector<T, my_allocator<T>>; int main() { using func_t = int (*)(int, int); my_vector<func_t> v = {add, sub}; }
  • 28.  今までは暗黙にコンパイラに自動生成される関数 はコンストラクタ、コピーコンストラクタ、コ ピー代入演算子、デストラクタの4つだったが C++11ではムーブコンストラクタ、ムーブ代入 演算子の2つが増え、全部で6つになった  サンプル無し
  • 29.  オブジェクトが左辺値か右辺値かによってメンバ 関数を呼び分けられるようになる struct hoge { void func() & { cout << "lvaluen"; } void func() && { cout << "rlvaluen"; } }; int main() { hoge h; h.func(); hoge().func(); }
  • 30.  ユーザーが任意の型のリテラルを表すサフィック スを定義できる string operator ""_s(const char* str, size_t size) { return {str, size}; } int main() { cout << "hello"_s.size() << endl; }
  • 31.  変数や関数がコンパイル時定数、コンパイル時計 算可能である(結果として副作用がなく、参照透過 性があることを保証している)ことを表す constexpr int factorial(int n) { return n == 0 ? 1 : n * factorial(n - 1); } int main() { array<int, factorial(4)> ar; }
  • 32.  関数が例外送出するか有無を指定できる  式が例外を投げるか判定できる演算子 class integer { public: integer(int value) : value_(value) {} int get() const noexcept {return value_;} private: int value_; }; int get(const integer& in) noexcept(noexcept(in.get())) { return in.get(); } int main() { integer n{42}; cout << get(n) << endl; }
  • 33.  alignof 変数や型のアライメントを取得する  alignas 変数宣言の際、アライメントを指定する int main() { alignas(int) unsigned char c[32]; alignas(4) int a; constexpr int int_align = alignof(int); }
  • 34.  ローカルクラス、無名クラスをテンプレート引数 にする(VC10)  生文字リテラル(VC11CTP)  二重になった山閉じ括弧の解釈(VC8)
  • 35. C++11 VC++の書き方 バージョン alignas(x) __declspec(align(x)) VC7 alignof(T) __alignof(T) VC7 thread_local __declspec(thread) VC10 [[noreturn]] __declspec(noreturn) VC7
  • 36.  制限を無くしたunion  属性  char16_t/char32_t  inline namespace  継承コンストラクタ  thread_local  Unicode文字列リテラル  リテラル型に対するconstexpr
  • 37.  始めに新しく登場したヘッダを紹介します。  次に既存のヘッダに追加されたクラス、関数、型 など紹介します  全て紹介するわけではありません  各クラスのメンバについては触れません  関数などのオーバーロードや事前/事後条件や計 算量や引数/戻り値型の要求などについては触れ ません
  • 38.  組み込みの配列型にSTLコンテナのインターフェ イスを持たせたクラス  固定長シーケンスコンテナ  組み込み配列とパフォーマンスは同じ
  • 39.  ビット数が規定された整数型のtypedefや、マク ロを定義している  intN_t(Nビットサイズの符号あり整数型)  uint_leastN_t(少なくともNビットサイズのある符 号なし整数型)  PTRDIFF_MAX(std::ptrfiff_tの最大値)  など
  • 40.  単方向リスト(listは双方向リストで、ノードに2 つのポインタを持つが、こちらは1つ)  C言語で単方向リストを実装する場合と比べて、 空間計算量も時間計算量もゼロオーバーヘッドで あるよう設計されている
  • 41.  正規表現処理を行うクラス、関数が定義されてい る  正規表現のパターンを表したregex、マッチした 結果を格納するmatchを使う
  • 42.  文字コード変換を行う  ライブラリはあるが肝心のUnicodeリテラルや char32_tなどにVCが対応してないので余り意味 が無い
  • 43.  擬似乱数を扱うための、擬似乱数生成器、分布生 成器、真の乱数生成器、シード数列などが定義さ れている  mt19937(パラメータ定義済み32bitメルセンヌツ イスターエンジン)や、 linear_congruential_engine(線形合同法エンジ ン)などの擬似乱数生成器、 uniform_int_distribution(一様整数分布生成器)、 normal_distribution(正規分布生成器)などがある
  • 44.  型の特性、操作を行うメタ関数が定義されている  conditional(コンパイル時条件式)、is_same(2つ の型が同じ型か判定する)、coomon_type(共通の 型を取得する)などがある
  • 45.  type_infoを連想配列のキーとして使えるように 比較演算子などを定義している
  • 46.  pairが2つの型の組みを表すが、tupleは任意個の 型を値を保持できる  型リスト、無名構造体という見方もできる  要素はstd::get関数を使う
  • 47.  OSが出力するエラーを扱う機能を提供する  主にハードウエアやプログラム外でのエラーを通 知する
  • 48.  setと比べ、キーの順序ではなくキーのhash値に 基いて格納される連想配列  ソートはされておらず、順序は有意ではないが検 索がsetよりも高速なため、ソートされている必 要がないのならこちらを使うと良い
  • 49.  mapと比べ、キーの順序ではなくキーのhash値 に基いて格納される連想配列  ソートはされておらず、順序は有意ではないが検 索がmapよりも高速なため、ソートされている必 要がないのならこちらを使うと良い
  • 50.  vector<string>のような要素とコンテナで両方 にメモリ確保が必要になった場合、コンテナと要 素で同じアロケータからメモリ確保するためのア ロケータアダプタを提供する。
  • 51.  有理数(分数)の定数を表すクラス  単位として使われるためのtypedefがある  四則演算、比較演算もある
  • 52.  時間に関するライブラリ  std::chrono名前空間に定義  時間の任意の精度・表現で取得、計算、単位変換 など行える
  • 53.  ユーザー定義型が初期化リストで初期化できるよ うにするためのクラスが定義されている  イテレータを使って要素を取得する
  • 54.  マルチスレッドプログラミングをするための基本 的な機能を提供する  スレッドを生成、終了することができる
  • 55.  変数へのスレッド間でデータをやり取りするため の基本的な操作であるアトミック操作を提供する。  分解不能読み書きが行える。  マルチスレッドプログラミングについて熟知して いればmutexを用いるよりパフォーマンスが向上 する可能性があるが、扱いが難しく逆にパフォー マンスが劣化する可能性もあるので、mutexのパ フォーマンスが問題にならない限り使用しなくて 良い
  • 56.  スレッド間で安全にデータをやり取りするための 排他制御を提供する  排他制御mutex、それをRAIIで扱えるlock_guard、 指定された関数を1度だけ呼び出すcall_onceなど がある
  • 57.  マルチスレッドプログラミングのデザインパター ンの1つであるfuture/promiseパターンを実現す る機能を提供する  データや例外を設定するpromise、データや例外 を取得するfuture、future/promiseを簡単に行え るようラップしたasyncなどがある
  • 58.  並行キューを実現する機能を提供する  特定のイベント、条件を満たすまでスレッドの実 行を待機させる。基本的なスレッド同期の仕組み
  • 59.  面倒なので数が多いので内容の説明はせず、列挙 だけしていきます  <ヘッダ名>(C++11のクラス、関数が追加され たVCのバージョン)
  • 60.  all_of, any_of, none_of  find_if_not  copy_n, copy_if  move, move_backward  suffle  is_partitioned  partition_copy, partition_point  is_sorted, is_sorted_until  is_heap, is_heap_until  minmax, minmax_element  is_permutation
  • 61.  bitset ◦ all
  • 62.  LLONG_MIN, LLONG_MAX  ULLONG_MAX
  • 63.  function, bad_function_call  bind, is_bindexpression, is_placeholder, placeholders::_1, placeholders_2, placeholders::_N, mem_fn  reference_wrapper, ref, cref  hash
  • 64.  next, prev  move_iterator  begin, end
  • 65.  numeric_limit ◦ lowest, max_digits10
  • 66.  wstring_convert  wbuffer_convert
  • 67.  iota
  • 68.  type_info ◦ hash_code
  • 69.  deque ◦ cbegin, cende, crbegin, crend ◦ shrink_to_fit ◦ emplace, emplace_back, emplace_front
  • 70.  list ◦ cbegin, cende, crbegin, crend ◦ emplace, emplace_back, emplace_front
  • 71.  set ◦ cbegin, cende, crbegin, crend ◦ emplace, emplace_hint  multi_set ◦ cbegin, cende, crbegin, crend ◦ emplace, emplace_hint
  • 72.  map ◦ cbegin, cende, crbegin, crend ◦ at ◦ emplace, emplace_hint  multi_map ◦ cbegin, cende, crbegin, crend ◦ at ◦ emplace, emplace_hint
  • 73.  queue ◦ emplace, swap ◦ reference, const_reference  priority_queue ◦ emplace, swap ◦ reference, const_reference  swap
  • 74.  stack ◦ emplace, swap ◦ reference, const_reference  swap
  • 75.  vector ◦ cbegin, cende, crbegin, crend ◦ shrink_to_fit ◦ emplace, emplace_back
  • 76.  basic_string ◦ cbegin, cende, crbegin, crend ◦ shrink_to_fit ◦ pop_back, back, front  stoi, stol, stoul, stoll, stoull, stof, stod, stold
  • 77.  to_string  to_wstring  hash
  • 78.  nullptr_t(VC10)  max_align_t(VC11)
  • 79.  bad_array_new_length(VC10)  get_new_handler(VC11)
  • 80.  unitilialized_copy_n  shared_ptr, unique_ptr, weak_ptr, enable_shared_from_this, bad_weak_ptr, owner_less, default_delete, addresso  make_shared, allocate_shared, static_pointer_cast, dynamic_pointer_cast, const_pointer_cast  pointer_safety, get_pointer_safety, declare_reachable, undeclare_reachable, declare_no_reachable, undeclare_no_reachable
  • 81.  align, pointer_traits  allocator_traits, allocator_arg_t, allocator_arg, uses_allocator
  • 82.  forward, move(VC10)  tuple_size, tuple_element, get(VC10)  move_if_noexcept(VC11)  declval, piecewise_constrcut_t, piecewise_constrcut(VC11)
  • 83.  acos, asin, atan, acosh, asinh, atanh  proj
  • 84.  nested_exception  get_unexpected  exception_ptr, current_exception, rethrow_exception, make_exception_ptr  throw_with_nested, rethrow_if_nested
  • 85.  HUGE_VALF, HUGE_VALL, INFINITY, NAN  FP_INFINITE, FP_NAN, FP_NORMAL, FP_SUBNORMAL, FP_ZERO  FP_FAST_FMA, FP_FAST_FMAF, FP_FAST_FMAL  FP_ILOGB0, FP_ILOGBNAN  MATH_ERRNO, MATH_ERREXCEPT  math_errhandling
  • 86.  DECIMAL_DIG  FLT_EVAL_METHOD
  • 87.  <cfenv>  <cinttypes>  <ctgmath>  <cstdbool>  <cuchar>
  • 88.  <cmath> ◦ asinh, acosh, atanh ◦ exp2, expm1, log1p, log2 ◦ ilogb, logb, scalbn, scalbln ◦ cbrt, hypot ◦ erf, erfc, tgamma, lgamma ◦ trunc, round, nearbyint, rint, lrint, llrint ◦ remainder, remquo ◦ copysign, nan, nextafter, nexttoward ◦ fmax, fmin, fdim, fma ◦ fpclassify, isfinite, isinf, isnan, isnormal, signbit ◦ float_t, double_t,  ※グローバル領域には存在する。std名前空間に所属 していない
  • 89.  <string> ◦ u16string, u32string
  • 90.  C99やC++14などは一切触れておりません。  まさか90Pも行くとは思っていませんでした…  誰得  大人しくcpprefjpやcplusplusを見るのがいいと 思いましたまる
  • 91. Visual C++のC++14対応 言語機能&ライブラリ
  • 92.  一般化されたラムダキャプチャー(VC12CTP)  auto指定での一般関数の戻り値の型推論 (VC12CTP)  多相ラムダ(VC12CTP)  decltype(auto)(VC12CTP)  STLのユーザー定義リテラル対応(VC12CTP)
  • 93.  make_unique(VC12)  <type_traits>のusing alias(例えば make_unsigned_t, decay_tなど)(VC12)  begin()/cend()/rbegin()/rend()/crbegin()/cren d()(VC12)  多相ファンクタ(VC12)  async/await(VC12CTP)
  • 94.  一般化されたconstexpr  変数テンプレート  軽量コンセプト  dynarray