nekko1119
 身内向けです。
 Visual C++で使えるC++11の機能を、言語機能、
ライブラリに分けて紹介します。
 紹介する機能は私が独断と偏見で選んだ一部です。
全て紹介するわけではありません。
 コンパイラやライブラリのバグや部分対応までい
くと作業量大変なのでそこら辺は触れません
 内容の正しさには気をつけていますが間違えてい
る可能性もあります。
 サンプルコードは暗黙に必要なヘッダのインク
ルード、using namespace std;をしています。
 また、イメージとしてのサンプルで、実際には動
かないコードもあります。
 ライブラリの初出は所属する名前空間がstd::tr1
ではなくstdになった初めてのバージョンとしま
す
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
 2013年8月時点での細心のバージョンはVC12PR
です。
 それ以降のバージョン(VC12, VC12CTP)は公式で
公開されている開発の予定です
 変数の型を右辺式より推論する
 修飾子はつかない
 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;
}
 ヌルポインタを表すリテラル
 NULLはマクロで0に置換され、数値と曖昧となる
場合がある
void func(int){}
void func(int*){}
int main() {
func(10);
func(nullptr);
}
 戻り値を宣言の後ろに記述できる
 後述のdecltypeと合わせるとより便利
//int型を返す関数の宣言
int hoge();
auto foo() -> int;
//void (int)型の関数ポインタを返す関数の宣言
void (*f())(int);
auto g() -> void (*)(int);
 式から型を推論する
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;
}
 コンパイル時にassertチェックが出来る
 コンパイル時にチェックできるのは型とコンパイ
ル時定数の2つ
int main() {
static_assert(sizeof(long) >= 8, "64bit以上環境が必要です");
static_assert(_MCV_VER >= 1600, "VC++10.0以上のVC++コンパイラ
でなければなりません");
}
 従来の参照は正確には左辺値参照
 右辺値への参照ができるようになった
 機能としてはこれだけだが、本質は別にある。今
回は機能紹介が目的なので省略
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;
}
 その場に無名の一時関数オブジェクトを生成する
 戻り値の省略可能
 変数のコピーキャプチャ、参照キャプチャ可能
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;
});
}
 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); }
 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);
}
 従来の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;
}
}
}
 クラス、または仮想関数にfinal指定ができる
 クラスに指定した場合、そのクラスを基底クラス
にすることができなくなる
 仮想関数に指定した場合、その仮想関数をオー
ラーライドできなくなる
class hoge final {};
class foo : hoge {}; //エラー
class base {
virtual void func() final {}
};
class derived : base {
virtual void func() {}//エラー
};
 オーバーライドの意図を明確にするためにできた
 タイポやオーバーライドのつもりになっているミ
ス(気づきにくい)をエラーとして検出できる
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 {} //エラー
};
 引数が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);
}
 今まではクラステンプレートにはデフォルトテン
プレート引数が指定できたが、関数では無理だっ
た(オーバーロードで同様のことが実現できるた
め)が、できるようになった
template <class T, class D = default_delete<T>>
unique_ptr<T, D> make_unique(T* p, D d = D()) {
return {p, forward<D>(d)};
}
 コンストラクタから同クラスの他のコンストラク
タを呼び出すことが可能になる
 処理を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_;
};
 今まで引数無しコンストラクタ構文での初期化は
関数宣言とみなされたり、初期化リストは配列型
や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};
}
 任意の型の引数を任意個取ることができるクラス
/関数テンプレートを作ることができる。
 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);
}
 初期化リストに専用の型が出来た。これを引数に
とるコンストラクタを定義することでユーザー定
義型でも初期化リストが使えるようになった。
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};
}
 非静的データメンバを宣言と同時に初期化出来る
 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");
}
 コンパイラによって自動生成される関数が既定の
動作であることを明示する
class hoge {
public:
hoge() = default;
hoge(const hoge&) = default;
~hoge() = default;
hoge& operator=(const hoge&) = default;
//VC12の時点でmove ctor/assignは自動生成されない
};
 望まない型変換や関数テンプレートのインスタン
ス化を抑止できる
 自動生成される関数の生成を抑止できる
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;
};
 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};
}
 今までは暗黙にコンパイラに自動生成される関数
はコンストラクタ、コピーコンストラクタ、コ
ピー代入演算子、デストラクタの4つだったが
C++11ではムーブコンストラクタ、ムーブ代入
演算子の2つが増え、全部で6つになった
 サンプル無し
 オブジェクトが左辺値か右辺値かによってメンバ
関数を呼び分けられるようになる
struct hoge {
void func() & {
cout << "lvaluen";
}
void func() && {
cout << "rlvaluen";
}
};
int main() {
hoge h;
h.func();
hoge().func();
}
 ユーザーが任意の型のリテラルを表すサフィック
スを定義できる
string operator ""_s(const char* str, size_t size) {
return {str, size};
}
int main() {
cout << "hello"_s.size() << endl;
}
 変数や関数がコンパイル時定数、コンパイル時計
算可能である(結果として副作用がなく、参照透過
性があることを保証している)ことを表す
constexpr int factorial(int n) {
return n == 0 ? 1 : n * factorial(n - 1);
}
int main() {
array<int, factorial(4)> ar;
}
 関数が例外送出するか有無を指定できる
 式が例外を投げるか判定できる演算子
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;
}
 alignof 変数や型のアライメントを取得する
 alignas 変数宣言の際、アライメントを指定する
int main() {
alignas(int) unsigned char c[32];
alignas(4) int a;
constexpr int int_align = alignof(int);
}
 ローカルクラス、無名クラスをテンプレート引数
にする(VC10)
 生文字リテラル(VC11CTP)
 二重になった山閉じ括弧の解釈(VC8)
C++11 VC++の書き方 バージョン
alignas(x) __declspec(align(x)) VC7
alignof(T) __alignof(T) VC7
thread_local __declspec(thread) VC10
[[noreturn]] __declspec(noreturn) VC7
 制限を無くしたunion
 属性
 char16_t/char32_t
 inline namespace
 継承コンストラクタ
 thread_local
 Unicode文字列リテラル
 リテラル型に対するconstexpr
 始めに新しく登場したヘッダを紹介します。
 次に既存のヘッダに追加されたクラス、関数、型
など紹介します
 全て紹介するわけではありません
 各クラスのメンバについては触れません
 関数などのオーバーロードや事前/事後条件や計
算量や引数/戻り値型の要求などについては触れ
ません
 組み込みの配列型にSTLコンテナのインターフェ
イスを持たせたクラス
 固定長シーケンスコンテナ
 組み込み配列とパフォーマンスは同じ
 ビット数が規定された整数型のtypedefや、マク
ロを定義している
 intN_t(Nビットサイズの符号あり整数型)
 uint_leastN_t(少なくともNビットサイズのある符
号なし整数型)
 PTRDIFF_MAX(std::ptrfiff_tの最大値)
 など
 単方向リスト(listは双方向リストで、ノードに2
つのポインタを持つが、こちらは1つ)
 C言語で単方向リストを実装する場合と比べて、
空間計算量も時間計算量もゼロオーバーヘッドで
あるよう設計されている
 正規表現処理を行うクラス、関数が定義されてい
る
 正規表現のパターンを表したregex、マッチした
結果を格納するmatchを使う
 文字コード変換を行う
 ライブラリはあるが肝心のUnicodeリテラルや
char32_tなどにVCが対応してないので余り意味
が無い
 擬似乱数を扱うための、擬似乱数生成器、分布生
成器、真の乱数生成器、シード数列などが定義さ
れている
 mt19937(パラメータ定義済み32bitメルセンヌツ
イスターエンジン)や、
linear_congruential_engine(線形合同法エンジ
ン)などの擬似乱数生成器、
uniform_int_distribution(一様整数分布生成器)、
normal_distribution(正規分布生成器)などがある
 型の特性、操作を行うメタ関数が定義されている
 conditional(コンパイル時条件式)、is_same(2つ
の型が同じ型か判定する)、coomon_type(共通の
型を取得する)などがある
 type_infoを連想配列のキーとして使えるように
比較演算子などを定義している
 pairが2つの型の組みを表すが、tupleは任意個の
型を値を保持できる
 型リスト、無名構造体という見方もできる
 要素はstd::get関数を使う
 OSが出力するエラーを扱う機能を提供する
 主にハードウエアやプログラム外でのエラーを通
知する
 setと比べ、キーの順序ではなくキーのhash値に
基いて格納される連想配列
 ソートはされておらず、順序は有意ではないが検
索がsetよりも高速なため、ソートされている必
要がないのならこちらを使うと良い
 mapと比べ、キーの順序ではなくキーのhash値
に基いて格納される連想配列
 ソートはされておらず、順序は有意ではないが検
索がmapよりも高速なため、ソートされている必
要がないのならこちらを使うと良い
 vector<string>のような要素とコンテナで両方
にメモリ確保が必要になった場合、コンテナと要
素で同じアロケータからメモリ確保するためのア
ロケータアダプタを提供する。
 有理数(分数)の定数を表すクラス
 単位として使われるためのtypedefがある
 四則演算、比較演算もある
 時間に関するライブラリ
 std::chrono名前空間に定義
 時間の任意の精度・表現で取得、計算、単位変換
など行える
 ユーザー定義型が初期化リストで初期化できるよ
うにするためのクラスが定義されている
 イテレータを使って要素を取得する
 マルチスレッドプログラミングをするための基本
的な機能を提供する
 スレッドを生成、終了することができる
 変数へのスレッド間でデータをやり取りするため
の基本的な操作であるアトミック操作を提供する。
 分解不能読み書きが行える。
 マルチスレッドプログラミングについて熟知して
いればmutexを用いるよりパフォーマンスが向上
する可能性があるが、扱いが難しく逆にパフォー
マンスが劣化する可能性もあるので、mutexのパ
フォーマンスが問題にならない限り使用しなくて
良い
 スレッド間で安全にデータをやり取りするための
排他制御を提供する
 排他制御mutex、それをRAIIで扱えるlock_guard、
指定された関数を1度だけ呼び出すcall_onceなど
がある
 マルチスレッドプログラミングのデザインパター
ンの1つであるfuture/promiseパターンを実現す
る機能を提供する
 データや例外を設定するpromise、データや例外
を取得するfuture、future/promiseを簡単に行え
るようラップしたasyncなどがある
 並行キューを実現する機能を提供する
 特定のイベント、条件を満たすまでスレッドの実
行を待機させる。基本的なスレッド同期の仕組み
 面倒なので数が多いので内容の説明はせず、列挙
だけしていきます
 <ヘッダ名>(C++11のクラス、関数が追加され
たVCのバージョン)
 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
 bitset
◦ all
 LLONG_MIN, LLONG_MAX
 ULLONG_MAX
 function, bad_function_call
 bind, is_bindexpression, is_placeholder,
placeholders::_1, placeholders_2,
placeholders::_N, mem_fn
 reference_wrapper, ref, cref
 hash
 next, prev
 move_iterator
 begin, end
 numeric_limit
◦ lowest, max_digits10
 wstring_convert
 wbuffer_convert
 iota
 type_info
◦ hash_code
 deque
◦ cbegin, cende, crbegin, crend
◦ shrink_to_fit
◦ emplace, emplace_back, emplace_front
 list
◦ cbegin, cende, crbegin, crend
◦ emplace, emplace_back, emplace_front
 set
◦ cbegin, cende, crbegin, crend
◦ emplace, emplace_hint
 multi_set
◦ cbegin, cende, crbegin, crend
◦ emplace, emplace_hint
 map
◦ cbegin, cende, crbegin, crend
◦ at
◦ emplace, emplace_hint
 multi_map
◦ cbegin, cende, crbegin, crend
◦ at
◦ emplace, emplace_hint
 queue
◦ emplace, swap
◦ reference, const_reference
 priority_queue
◦ emplace, swap
◦ reference, const_reference
 swap
 stack
◦ emplace, swap
◦ reference, const_reference
 swap
 vector
◦ cbegin, cende, crbegin, crend
◦ shrink_to_fit
◦ emplace, emplace_back
 basic_string
◦ cbegin, cende, crbegin, crend
◦ shrink_to_fit
◦ pop_back, back, front
 stoi, stol, stoul, stoll, stoull, stof, stod, stold
 to_string
 to_wstring
 hash
 nullptr_t(VC10)
 max_align_t(VC11)
 bad_array_new_length(VC10)
 get_new_handler(VC11)
 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
 align, pointer_traits
 allocator_traits, allocator_arg_t, allocator_arg,
uses_allocator
 forward, move(VC10)
 tuple_size, tuple_element, get(VC10)
 move_if_noexcept(VC11)
 declval, piecewise_constrcut_t,
piecewise_constrcut(VC11)
 acos, asin, atan, acosh, asinh, atanh
 proj
 nested_exception
 get_unexpected
 exception_ptr, current_exception,
rethrow_exception, make_exception_ptr
 throw_with_nested, rethrow_if_nested
 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
 DECIMAL_DIG
 FLT_EVAL_METHOD
 <cfenv>
 <cinttypes>
 <ctgmath>
 <cstdbool>
 <cuchar>
 <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名前空間に所属
していない
 <string>
◦ u16string, u32string
 C99やC++14などは一切触れておりません。
 まさか90Pも行くとは思っていませんでした…
 誰得
 大人しくcpprefjpやcplusplusを見るのがいいと
思いましたまる
Visual C++のC++14対応
言語機能&ライブラリ
 一般化されたラムダキャプチャー(VC12CTP)
 auto指定での一般関数の戻り値の型推論
(VC12CTP)
 多相ラムダ(VC12CTP)
 decltype(auto)(VC12CTP)
 STLのユーザー定義リテラル対応(VC12CTP)
 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)
 一般化されたconstexpr
 変数テンプレート
 軽量コンセプト
 dynarray

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