VC++で始めるC++11/14 
発表する人:くれすと 
わんくま同盟 大阪勉強会 #61
わんくま同盟 大阪勉強会 #61 
自己紹介 
● H.N:Crest 
● Twitter @thayamizu 
● Blog http://d.hatena.ne.jp/Crest 
● 博士(情報学) 
● 職業:プログラマ 
● よく使う言語:C++/VC++, C#, VB 
● 趣味:カラオケ・プログラミング・イラスト・読 
書・スクフェス
わんくま同盟 大阪勉強会 #61 
自己紹介 
● H.N:Crest 
● Twitter @thayamizu 
● Blog http://d.hatena.ne.jp/Crest 
● 博士(情報学) 
● 職業:プログラマ 
● よく使う言語:C++/VC++, C#, VB 
● 趣味:カラオケ・プログラミング・イラスト・読 
書・スクフェス
勉強会・読書会やってます 
● 型システム入門読書会 (開催中) 
わんくま同盟 大阪勉強会 #61
わんくま同盟 大阪勉強会 #61 
C++11とC++14 
● C++11はC++03からのメジャーアップデート 
● C++14はC++11からのマイナーアップデート 
● C++14ではC++11で制定されたいくつかの機 
能に対してより洗練された機能を提供 
– ジェネリックラムダ、一般化されたラムダキャプチャ 
– 関数の戻り値の型推論
わんくま同盟 大阪勉強会 #61 
C++のロードマップ
わんくま同盟 大阪勉強会 #61 
コンパイラについて 
● 以下のコンパイラを使いました 
● GCC 4.8.3(cygwin edition) 
● Visual Studio Professional 2013 
● Visual Studio Ultimate 2015 Preview
わんくま同盟 大阪勉強会 #61 
VC++ の対応状況 
● Preview段階ですが、Visual Studio 2013と 
比べるとかなりがんばって標準対応をしてる 
VC++ Team Blog
Cross-Platform Mobile Development with Visual C++ 
● 余談ですが、Visual Studio 2015からはAndr 
oid/iOS等のモバイル向けの開発ができるよ 
うにClang/LLVMが使えるようになっています 
– Clangに負けないように頑張ってほしいですね 
わんくま同盟 大阪勉強会 #61
わんくま同盟 大阪勉強会 #61 
お約束 
この場における発言は個人のものであり、所 
属する組織等とは関係ありません
コア言語機能 
わんくま同盟 大阪勉強会 #61
わんくま同盟 大阪勉強会 #61 
初期化リスト 
● <initializer_list>ヘッダが追加された 
– 初期化リストは再帰的に適用されるので、構造体の配列 
や構造体を含む構造体にも使用できる 
● 後述の統一的初期化構文の一端を担う 
● STLコンテナにinitializer_listを引数に取るコ 
ンストラクタが追加された 
vector<int> v = { 1, 2, 3 }; 
X x = { 10, 20, 30 };
わんくま同盟 大阪勉強会 #61 
統一的な初期化 
● C++03 では、初期化の方法に問題があった 
– 引数なしのコンストラクタは関数宣言と同じ形であるため 
コンパイラが正しく判定できなかった 
– 初期化リストはPOD型のみ 
● C++11では、初期化構文の拡張とinitializer_l 
istの導入によって、配列・集成体・ユーザ定 
義型を統一的に初期化できるようになった
右辺値参照とムーブセマンティクス 
● 一時オブジェクトは壊しても問題ない 
– 「いつ壊しても良い」ということを明示的に指定する 
– 技術的には古くからあるイディオム(auto_ptrなど)をC++ 
の構文として取り込んだもの 
● 最適化されたコピーまたは所有権の移動を 
実現できるのでパフォーマンスの向上が見込 
める 
型名&& 変数名 = 初期値;//右辺値参照を明示的に受けれる変数 
X(X&& x) {...}        //ムーブコンストラクタ 
X& operator=(X&& x) {...} //ムーブ代入演算子 
わんくま同盟 大阪勉強会 #61
わんくま同盟 大阪勉強会 #61 
右辺値と左辺値 
int x = 0; 
int* px = &x 
int& rx = x; 
int && rrx = 0; 
Point p; 
p.x = 0; 
0 
3.14 
nullptr 
10 * 10 
sqrt (x*x + y*y) 
static_cast<int>(x) 
左辺値(lvalue) 
名前付きのオブジェクト 
右辺値(rvalue) 
一時オブジェクト
わんくま同盟 大阪勉強会 #61 
範囲ベースFor 
● コンテナの最初から最後までを走査する 
– foreach 
– コンテナの要素を簡単に列挙できる 
● 従来のfor文は冗長で書くのが面倒だった 
//これまでのfor 
for (vector<int>::iterator it = vec.begin(); it != vec.end(); ++it) 
//範囲ベースfor 
for (int v : vec) 
//autoと併用 
for (auto v : vec)
わんくま同盟 大阪勉強会 #61 
ラムダ式 
● <algorithm>に定義されている関数テンプ 
レートは述語を引数に取るのでその場で関数 
オブジェクトを生成したい場面がある 
● C++11ではラムダ関数が定義できるように 
なった 
– C#でいうところの匿名ラムダ式 
– 実際には関数オブジェクトを生成するためのシンタックス 
シュガー
2.関数の引数リスト 
・C++14からは引数の型にauto 
が指定できる 
わんくま同盟 大阪勉強会 #61 
ラムダ式の構文 
[= &] (引数リスト) ->戻り値の型 { 
...関数本体... 
} 
1.キャプチャリスト 
 = … コピーキャプチャ 
 & ... リファレンスキャプチャ 
・キャプチャした変数に名前付け 
でき,複数のキャプチャ方法が選 
択できる(C++14) 
3.関数の戻り値の型 
・ラムダ式では関数の戻り値の型 
 は後置した形で記述 
・関数の戻り値の型は省略可能
ラムダ式 
string str = "hello, world!"; 
cout << "before : " << str << endl; 
//大文字小文字を変換する 
transform(str.begin(), str.end(), str.begin(), [](char c) { 
return toupper(c); 
}); 
cout << "after : " << str << endl; 
わんくま同盟 大阪勉強会 #61
わんくま同盟 大阪勉強会 #61 
ジェネリックラムダ 
● C++11のラムダ式にはテンプレートを指定で 
きないという重大な欠陥がある 
● C++14ではこれを解消するためにジェネリッ 
クラムダが導入された 
//大文字小文字を変換する 
transform(str.begin(), str.end(), str.begin(), [](auto c) { 
return toupper(c); 
});
一般化されたラムダキャプチャ 
● ラムダ式のキャプチャ時に、変数名を付けれる 
ようにする 
– キャプチャする変数1つに対して、複数のキャプチャ方法を 
わんくま同盟 大阪勉強会 #61 
適用できる 
int x= 3; 
// x にyという変数名を付けてラムダ式内で使用する 
auto f = [y = x ] { ... } 
// yはxをコピーキャプチャした変数、zはxを参照キャプチャした変数 
auto f = [y = x, &z = x] { ... };
わんくま同盟 大阪勉強会 #61 
noexcept 
● 例外を投げないことを明示するnoexceptキー 
ワードが追加された 
– 例外を投げない例外保障(nothrow guarantee)を満たす 
ものに付ける 
– throwキーワードを使用した関数の例外指示が非推奨に 
//C++11 
void swap(char* lhs, char* rhs) noexcept { 
…. 
} 
//C++03(非推奨) 
void swap(char* lhs, char* rhs) throw() { 
... 
}
わんくま同盟 大阪勉強会 #61 
型推論 -auto 
● autoキーワードの意味が変更された 
– 以前は自動記憶クラス指定子(ローカル変数宣言) 
– C++11以降は、右辺の式から型を推論する 
● autoの推論はCV修飾・参照は消す 
– decayされる
auto 
//cv修飾と参照は消えてしまう 
int i = 10;//int 
int& ri = i;//int& 
auto ai = ri;//int 
わんくま同盟 大阪勉強会 #61 
//cv修飾と参照をつける 
int i = 10;//int 
int& ri = i;//int& 
auto& ai = ri;//int&
わんくま同盟 大阪勉強会 #61 
型推論 - decltype 
● autoキーワードとともに追加された型推論の 
ためのキーワード 
● autoの推論はCV修飾・参照は消すがdeclty 
peでは消されない 
– そのままの型になる 
– ただし()で包むと左辺値参照となる
わんくま同盟 大阪勉強会 #61 
decltype 
int i = 1; 
decltype(i) d2; //int 
int& ri = i; 
decltype(ri) d3 = ri; //int& 
int&& mi = move(i); 
decltype(mi) d4 = move(mi); //int&& 
const int ci = 10; 
decltype(ci) d5 = ci; //const int
型推論 - 関数の戻り値の型推論 
● 関数の戻り値の型を推論する 
– テンプレートなどあらかじめ戻り値の型がわからない 
● 関数テンプレートはメタプログラミングやオーバーロードにより、 
戻り値の型が型に依存して変わる 
– 型名が非常に長い 
● ラムダ式以外の通常の関数にも関数の戻り 
値の推論を広げると、ヒントが欲しい場合が 
ある 
わんくま同盟 大阪勉強会 #61 
– decltype(auto)
わんくま同盟 大阪勉強会 #61 
Constexpr 
● コンパイル時定数式 
● C++11ではconstexpr関数の制約はかなり厳 
しかった 
– 変数宣言ができない 
– 関数は実質return文一つのみ 
– 条件分岐は3項演算子のみ 
– 繰り返しは再帰で表現しなければならない 
● C++14ではこれがかなり改善されたがVC++ 
ではまだ未対応
わんくま同盟 大阪勉強会 #61 
Unicode対応 
● Unicode文字を表現する型としてchar16_tとc 
har32_tが追加された 
● char16_tおよびchar32_tはそれぞれUtf16、 
Utf32としてエンコードされるそうです 
– サロゲートペア・異体字セレクタに関する問題はまだ残っ 
ている 
● リテラルにutf8リテラル、char16_tリテラル、 c 
har32_tリテラルが追加
わんくま同盟 大阪勉強会 #61 
Unicode 
//unicode文字 
char16_t u16_char = u'a'; 
char32_t u32_char = U'a'; 
//unicode文字列 
char* u8_char = u8"utf8 string lietral"; 
char16_t* u16_char = u"utf16 string lietral"; 
char32_t* u32_char = U"utf32 string lietral"; 
//std::basic_string<T>のchar16_tとchar32_tに対する特殊化 
std::string u8Str = u8"utf8 string"; 
std::u16string u16Str = u"char16_t string"; 
std::u32string u32Str = U"char32_t string";
わんくま同盟 大阪勉強会 #61 
生文字列リテラル 
● エスケープ不要な文字列リテラル 
– C#でいう@文字列 
● 書式文字列を使うケースは意外に多いので 
使えそうなケースは多いかも 
//C++14 
sprintf(json, R"({"user_id": %d, "name": "%s"})", user_id, 
name); 
//C++11以前 
sprintf(json, "({"user_id": %d, "name": "%s"})", user_id, 
name);
わんくま同盟 大阪勉強会 #61 
static_assert 
● コンパイル時にアサートをする 
● アサートに失敗するとコンパイルが停止する 
● type_traitsと組み合させてテンプレートパラ 
メータの制約チェックに使ったり、コンパイル 
時計算の検証に利用する
わんくま同盟 大阪勉強会 #61 
POD型の制約の緩和 
● Cと互換性のあるクラス型をPlain Old Data 
(POD) と呼ぶ 
– C++03 におけるルールは必要以上に厳しかった 
● POD型であるクラス(構造体) trivial かつsta 
ndard-layout であり、すべての非静的データ 
メンバがPOD型である
わんくま同盟 大阪勉強会 #61 
default/delete指定 
● 特殊メンバ関数(コンストラクタ・デストラクタ 
など)を生成するかどうかを指定することがで 
きるようになった 
● 関数宣言時に= defaultまたはdeleteを指定 
する 
struct X { 
X() = default; //コンストラクタを生成するように指定する 
~X() = default;//デストラクタを生成するように指定する 
}; 
struct Y{ 
Y() = delete;//コンストラクタを生成させない 
~Y() = delete;//デストラクタを生成させない 
};
わんくま同盟 大阪勉強会 #61 
委譲コンストラクタ 
● コンストラクタから別のコンストラクタを呼び出 
すことができる 
– これまでのC++はコンストラクタからコンストラクタを呼び 
出すことができなかった 
● ほかのコンストラクタを別のコンストラクタから 
少ない変更で再利用可能になる 
struct X{ 
int mValue; 
//コンストラクタから別のコンストラクタを呼び出す 
X() : X(0){ } 
X(int v) :mValue(v) { } 
};
わんくま同盟 大阪勉強会 #61 
継承コンストラクタ 
● 派生クラスにおいて継承元のコンストラクタを 
呼び出すことができる 
● コンパイラは派生クラスのコンストラクタ呼び 
出しを基底クラスのコンストラクタ呼び出しへ 
と転送するコードを生成する 
struct Base{ 
int value; 
Base(int value) : value(value){} 
}; 
struct X : public Base{ 
// 基底クラスのコンストラクタを派生クラスで使用できるように定義 
using Base::Base; 
};
強く型付けされた列挙型 
● 列挙型は型安全でなかった 
– 実質的には整数として扱われているため、型の違う列挙 
型の値同士が比較ができてしまう 
● 列挙型はスコープを持たない 
● C++11ではenum キーワードとclass(struct) 
キーワードを組み合わせた enum class宣言 
を用いることで、型安全でスコープを持つ列 
挙型を表現できる 
わんくま同盟 大阪勉強会 #61
わんくま同盟 大阪勉強会 #61 
明示的な変換関数 
● コンストラクタを暗黙的な型変換関数として扱 
われないようにするための修飾子として、exp 
licitキーワードが導入されている 
– これは変換関数には効果が無いため暗黙の変換ができ 
てしまう 
struct X { 
X():ptr_(new int()) {} 
~X() { delete ptr_; ptr_ = nullptr; } 
explicit operator bool() { 
return ptr_ != nullptr; 
} 
private: 
int * ptr_; 
};
可変長引数テンプレート 
● 可変長のテンプレートパラメータを持つテンプ 
レートを作成する 
– std::funciton, std::bind, std::tupleっぽいクラステンプ 
レートを使おうとすると 引数の数の異なる関数テンプ 
レート・クラステンプレートを実装する必要があった 
– 引数の数の異なる関数テンプレート・クラステンプレートを 
わんくま同盟 大阪勉強会 #61 
実装せずに済む
可変長引数テンプレート 
template<typename T, typename U> 
T min(const T& lhs, const U& rhs) { 
return lhs > rhs ? rhs : lhs; 
} 
template<typename T, typename ... U> 
T min(const T& head, U... tail) { 
return min(head, min(tail...)); 
} 
cout << min(50, 23, 123, 111) << endl; 
わんくま同盟 大阪勉強会 #61
わんくま同盟 大阪勉強会 #61 
エイリアステンプレート 
● using を使ってテンプレートに別名をつける 
● テンプレートに対してtypedefを作ることはで 
きなかった 
– テンプレートパラメータを指定したものに対しては可能 
//typedef と同様の形式 
using counter = long; 
//関数ポインタ 
using function = void(*)(int); 
//パラメータを指定したものに別名を付ける 
using int_vector = vector < int > ; 
//テンプレートに対して、別名をつける 
template<class T> using ptr = T*;
わんくま同盟 大阪勉強会 #61 
制限のない共用体 
● 共用体のメンバの制限が取り払われた 
● POD型じゃなくても共用体のメンバとすること 
ができる 
struct Point{ 
int x, y; 
Point(int x1, int y1) 
:x(x1), y(y1) {} 
Point operator +(const Point& p) { 
return Point(x + p.x, y + p.y); 
} 
}; 
union X { 
int i; 
double d; 
Point p; //メンバ関数が定義されていてもunionのメンバとして使用できる 
};
わんくま同盟 大阪勉強会 #61 
sizeofの拡張 
● 非静的データメンバに対してインスタンス作 
成なしにsizeof演算子を適用できる
ライブラリの拡充 
わんくま同盟 大阪勉強会 #61
わんくま同盟 大阪勉強会 #61 
正規表現 std::regex 
● <regex>ヘッダが追加 
● 正規表現を使ったパターンマッチングが扱え 
る 
– 検索・置換・照合
Regex 照合 
// <で始まって>で終わる文字列にマッチする正規表現で検索 
std::regex r("<[^>]+>"); 
//正規表現にマッチした結果を格納する 
std::smatch m; 
string str1 = R"(<html></html>)"; 
if (regex_match(str1, r)) { 
cout << "pattern matched" << endl; 
} 
else { 
cout << "pattern matched" << endl; 
} 
わんくま同盟 大阪勉強会 #61
Regex 検索 
// <で始まって>で終わる文字列にマッチする正規表現で検索 
std::regex r("<[^>]+>"); 
//正規表現にマッチした結果を格納する 
std::smatch m; 
//検索対象の文字列 
string str1 = R"(<Window>Hello World</ Window>)"; 
//検索をするには、regex_searchを使う 
if (regex_search(str1, m, r)) { 
cout << "found (pos=" << m.position() << ")" << endl; 
cout << " ==> " << m.str() << endl; 
} 
わんくま同盟 大阪勉強会 #61
わんくま同盟 大阪勉強会 #61 
乱数 
● <random>ヘッダが追加 
– 高性能な乱数生成器および分布関数アルゴリズムが数 
多く用意されている 
– メルセンヌツイスタ法 
– 一様分布、正規分布、ベルヌーイ分布、サンプリング分布 
etc. 
● 分野によってはかなり便利そう
Random - 乱数生成器 
//乱数生成器 
std::random_device rd; 
std::mt19937 mt(rd()); 
for (int i = 0; i < 10; ++i) { 
  std::cout << mt() << 'n'; 
} 
cout << endl; 
わんくま同盟 大阪勉強会 #61
わんくま同盟 大阪勉強会 #61 
Random 一様分布 
std::random_device rd; 
std::mt19937 mt(rd()); 
//整数の分布ならstd::uniform_int_distribution 
std::uniform_int_distribution<int> id(1, 6); 
//実数の分布ならstd::uniform_real_distribution 
std::uniform_real_distribution<double> urd(0.0, 10.0); 
for (int i = 0; i < 10; ++i) { std::cout << id(mt) << 'n'; } 
for (int i = 0; i < 10; ++i) { std::cout << rd(mt) << 'n'; }
わんくま同盟 大阪勉強会 #61 
Random 正規分布 
std::random_device rd; 
std::mt19937 mt(rd()); 
//正規分布 
std::normal_distribution<> nd(5, 2); 
std::map<int, int> hist; 
for (int n = 0; n < 10000; ++n) { 
++hist[round(nd(mt))]; 
} 
for (auto p : hist) { 
std::cout << std::fixed << std::setprecision(1) << std::setw(2) 
<< p.first << ' ' << std::string(p.second / 200, '*') << 'n'; 
}
わんくま同盟 大阪勉強会 #61 
スマートポインタ 
● 3種類のスマートポインタが導入された 
所有権型のunique_ptr 
– 参照カウント型のshared_ptr 
– 弱参照式のweak_ptr 
● com_ptr/intrusive_ptr相当は標準にはない 
のでCOMを使うときはboostintrusive_ptrかa 
tlbaseのComPtrを使うか自作する必要があ 
る
スマートポインタ shared_ptr 
struct X { 
X() { cout << "call constructor" << endl; } 
~X() { cout << "call destructor" << endl; } 
}; 
int main() { 
shared_ptr<X> p; 
{ 
shared_ptr<X> p1 = shared_ptr<X>(new X()); 
p = p1; 
shared_ptr<X> p2 = make_shared<X>(); 
} 
わんくま同盟 大阪勉強会 #61 
cout << "exit scope" << endl; 
}
スマートポインタ unique_ptr 
struct X { 
X() { cout << "call constructor" << endl; } 
~X() { cout << "call destructor" << endl; } 
}; 
int main() { 
unique_ptr<X> p; 
{ 
unique_ptr<X> p1(new X()); 
//p = p1; //コピー代入はできないがムーブ代入は可能 
p = move(p1); 
unique_ptr<X> p2(make_unique<X>(); 
} 
cout << "exit scope" << endl; 
} 
わんくま同盟 大阪勉強会 #61
わんくま同盟 大阪勉強会 #61 
ハッシュテーブル 
● <unordered_map><unordered_set>が追加 
● 以前はハッシュテーブルはなかった。 
– std::map、std::multimap、std::set、 std::multisetは赤 
黒木で実装されておりこれは2分探索木なのでハッシュで 
はない 
● ハッシュテーブルとして,std::unordered_ma 
p, std::unordered_setが追加された
わんくま同盟 大阪勉強会 #61 
thread 
● <thread>が追加 
● 関数、メンバ関数、ラムダ式などからスレッド 
オブジェクトを生成する 
– 機能としてはかなりプリミティブ 
– 環境独自のAPIを呼ぶ必要がなくなる 
● 移植性の向上
Thread 関数からスレッドオブジェクトを作る 
void do_work1() { 
for (auto i = 0; i < 10; ++i) cout << "working1 n"; 
} 
//関数からスレッドオブジェクトを生成 
thread th1(do_work1); 
わんくま同盟 大阪勉強会 #61 
//待機 
th1.join();
わんくま同盟 大阪勉強会 #61 
Filesystem v3 
● <filesystem>が追加 
– C++1z(C++17)に導入予定だが先取りで入ってる 
– std::tr2::sys 名前空間が提供されている 
● OSの違いを気にすることなくファイル・ディレ 
クトリを扱うことができる 
– 環境独自のAPIを呼ぶ必要がなくなる 
● 移植性の向上
Filesystem 移動とコピー 
//ファイルのコピー 
const fs::path path("dir1/a.txt"); // コピ 
const fs::path dest("dir2/a.txt"); // コピー先 
try { 
fs::copy_file(path, dest); 
} 
catch (fs::filesystem_error& ex) { 
std::cout << ex.what() << std::endl; 
} 
わんくま同盟 大阪勉強会 #61 
//ファイルの移動 
const fs::path path("dir1/a.txt"); 
const fs::path dest("dir2/b.txt"); 
try { 
fs::rename(path, dest); 
} 
catch (fs::filesystem_error& ex) { 
std::cout << ex.what() << std::endl; 
}
Filesystem ファイルサイズの取得と存在チェック 
//ファイルの存在チェック 
const fs::path path("dir1/a.txt"); 
std::error_code error; 
const bool result = fs::exists(path, error); 
if (!result || error) { 
std::cout << "ファイルがない" << std::endl; 
} 
else { 
std::cout << "ファイルがあった" << std::endl; 
} 
//ファイルサイズを取得する 
const fs::path path("dir1/a.txt"); 
try { 
const auto size = fs::file_size(path); 
std::cout << "ファイルサイズ: " << size << std::endl; 
} 
catch (fs::filesystem_error& ex) { 
std::cout << ex.what() << std::endl; 
} 
わんくま同盟 大阪勉強会 #61
わんくま同盟 大阪勉強会 #61 
chrono 
● <chrono>ヘッダが追加 
– std::chrono名前空間が提供されている 
● 時間に関するユーティリティとして機能する関 
数・クラスを提供 
– 時間単位の変換 
– 経過時間の測定
std::chronoによる処理時間の計測 
//処理開始時刻 
auto start = std::chrono::system_clock::now(); 
// 重たーい処理 
auto j = 0UL; 
for (auto i = 1UL; i <= 100000000; ++i) { j += i; } 
//処理終了時刻 
auto end = std::chrono::system_clock::now(); 
// 終了時刻と開始時刻の差分 
auto diff = end - start; 
std::cout << "elapsed time = " 
//millisec単位に変換 
<< std::chrono::duration_cast<std::chrono::milliseconds>(diff).count() 
<< " msec." 
<< std::endl; 
わんくま同盟 大阪勉強会 #61
わんくま同盟 大阪勉強会 #61 
まとめ 
● VC++についてお話しました 
– 今回お話ししたのはほんの一部です。色々楽しい機能が 
追加されているので是非遊んでみてください 
– C++界隈ではなにかといわれるMSVCですが、標準対応 
は結構がんばっていると思います 
– VS2015のリリース版には入ってほしいなぁ
わんくま同盟 大阪勉強会 #61 
次に発表したいこと 
● C++AMP 
● 音声合成・音声認識
わんくま同盟 大阪勉強会 #61 
参考文献 
● ISO C++ 
● VC++ Team Blog 
● MSDN 
● 本の虫.江添亮のブログ 
● Faith and Brave C++で遊ぼう 
● Cpprefjp 
● C++ポケットリファレンス
ご清聴ありがとうございました 
わんくま同盟 大阪勉強会 #61

わんくま同盟大阪勉強会#61

  • 1.
  • 2.
    わんくま同盟 大阪勉強会 #61 自己紹介 ● H.N:Crest ● Twitter @thayamizu ● Blog http://d.hatena.ne.jp/Crest ● 博士(情報学) ● 職業:プログラマ ● よく使う言語:C++/VC++, C#, VB ● 趣味:カラオケ・プログラミング・イラスト・読 書・スクフェス
  • 3.
    わんくま同盟 大阪勉強会 #61 自己紹介 ● H.N:Crest ● Twitter @thayamizu ● Blog http://d.hatena.ne.jp/Crest ● 博士(情報学) ● 職業:プログラマ ● よく使う言語:C++/VC++, C#, VB ● 趣味:カラオケ・プログラミング・イラスト・読 書・スクフェス
  • 4.
    勉強会・読書会やってます ● 型システム入門読書会(開催中) わんくま同盟 大阪勉強会 #61
  • 5.
    わんくま同盟 大阪勉強会 #61 C++11とC++14 ● C++11はC++03からのメジャーアップデート ● C++14はC++11からのマイナーアップデート ● C++14ではC++11で制定されたいくつかの機 能に対してより洗練された機能を提供 – ジェネリックラムダ、一般化されたラムダキャプチャ – 関数の戻り値の型推論
  • 6.
    わんくま同盟 大阪勉強会 #61 C++のロードマップ
  • 7.
    わんくま同盟 大阪勉強会 #61 コンパイラについて ● 以下のコンパイラを使いました ● GCC 4.8.3(cygwin edition) ● Visual Studio Professional 2013 ● Visual Studio Ultimate 2015 Preview
  • 8.
    わんくま同盟 大阪勉強会 #61 VC++ の対応状況 ● Preview段階ですが、Visual Studio 2013と 比べるとかなりがんばって標準対応をしてる VC++ Team Blog
  • 9.
    Cross-Platform Mobile Developmentwith Visual C++ ● 余談ですが、Visual Studio 2015からはAndr oid/iOS等のモバイル向けの開発ができるよ うにClang/LLVMが使えるようになっています – Clangに負けないように頑張ってほしいですね わんくま同盟 大阪勉強会 #61
  • 10.
    わんくま同盟 大阪勉強会 #61 お約束 この場における発言は個人のものであり、所 属する組織等とは関係ありません
  • 11.
  • 12.
    わんくま同盟 大阪勉強会 #61 初期化リスト ● <initializer_list>ヘッダが追加された – 初期化リストは再帰的に適用されるので、構造体の配列 や構造体を含む構造体にも使用できる ● 後述の統一的初期化構文の一端を担う ● STLコンテナにinitializer_listを引数に取るコ ンストラクタが追加された vector<int> v = { 1, 2, 3 }; X x = { 10, 20, 30 };
  • 13.
    わんくま同盟 大阪勉強会 #61 統一的な初期化 ● C++03 では、初期化の方法に問題があった – 引数なしのコンストラクタは関数宣言と同じ形であるため コンパイラが正しく判定できなかった – 初期化リストはPOD型のみ ● C++11では、初期化構文の拡張とinitializer_l istの導入によって、配列・集成体・ユーザ定 義型を統一的に初期化できるようになった
  • 14.
    右辺値参照とムーブセマンティクス ● 一時オブジェクトは壊しても問題ない – 「いつ壊しても良い」ということを明示的に指定する – 技術的には古くからあるイディオム(auto_ptrなど)をC++ の構文として取り込んだもの ● 最適化されたコピーまたは所有権の移動を 実現できるのでパフォーマンスの向上が見込 める 型名&& 変数名 = 初期値;//右辺値参照を明示的に受けれる変数 X(X&& x) {...}        //ムーブコンストラクタ X& operator=(X&& x) {...} //ムーブ代入演算子 わんくま同盟 大阪勉強会 #61
  • 15.
    わんくま同盟 大阪勉強会 #61 右辺値と左辺値 int x = 0; int* px = &x int& rx = x; int && rrx = 0; Point p; p.x = 0; 0 3.14 nullptr 10 * 10 sqrt (x*x + y*y) static_cast<int>(x) 左辺値(lvalue) 名前付きのオブジェクト 右辺値(rvalue) 一時オブジェクト
  • 16.
    わんくま同盟 大阪勉強会 #61 範囲ベースFor ● コンテナの最初から最後までを走査する – foreach – コンテナの要素を簡単に列挙できる ● 従来のfor文は冗長で書くのが面倒だった //これまでのfor for (vector<int>::iterator it = vec.begin(); it != vec.end(); ++it) //範囲ベースfor for (int v : vec) //autoと併用 for (auto v : vec)
  • 17.
    わんくま同盟 大阪勉強会 #61 ラムダ式 ● <algorithm>に定義されている関数テンプ レートは述語を引数に取るのでその場で関数 オブジェクトを生成したい場面がある ● C++11ではラムダ関数が定義できるように なった – C#でいうところの匿名ラムダ式 – 実際には関数オブジェクトを生成するためのシンタックス シュガー
  • 18.
    2.関数の引数リスト ・C++14からは引数の型にauto が指定できる わんくま同盟 大阪勉強会 #61 ラムダ式の構文 [= &] (引数リスト) ->戻り値の型 { ...関数本体... } 1.キャプチャリスト  = … コピーキャプチャ  & ... リファレンスキャプチャ ・キャプチャした変数に名前付け でき,複数のキャプチャ方法が選 択できる(C++14) 3.関数の戻り値の型 ・ラムダ式では関数の戻り値の型  は後置した形で記述 ・関数の戻り値の型は省略可能
  • 19.
    ラムダ式 string str= "hello, world!"; cout << "before : " << str << endl; //大文字小文字を変換する transform(str.begin(), str.end(), str.begin(), [](char c) { return toupper(c); }); cout << "after : " << str << endl; わんくま同盟 大阪勉強会 #61
  • 20.
    わんくま同盟 大阪勉強会 #61 ジェネリックラムダ ● C++11のラムダ式にはテンプレートを指定で きないという重大な欠陥がある ● C++14ではこれを解消するためにジェネリッ クラムダが導入された //大文字小文字を変換する transform(str.begin(), str.end(), str.begin(), [](auto c) { return toupper(c); });
  • 21.
    一般化されたラムダキャプチャ ● ラムダ式のキャプチャ時に、変数名を付けれる ようにする – キャプチャする変数1つに対して、複数のキャプチャ方法を わんくま同盟 大阪勉強会 #61 適用できる int x= 3; // x にyという変数名を付けてラムダ式内で使用する auto f = [y = x ] { ... } // yはxをコピーキャプチャした変数、zはxを参照キャプチャした変数 auto f = [y = x, &z = x] { ... };
  • 22.
    わんくま同盟 大阪勉強会 #61 noexcept ● 例外を投げないことを明示するnoexceptキー ワードが追加された – 例外を投げない例外保障(nothrow guarantee)を満たす ものに付ける – throwキーワードを使用した関数の例外指示が非推奨に //C++11 void swap(char* lhs, char* rhs) noexcept { …. } //C++03(非推奨) void swap(char* lhs, char* rhs) throw() { ... }
  • 23.
    わんくま同盟 大阪勉強会 #61 型推論 -auto ● autoキーワードの意味が変更された – 以前は自動記憶クラス指定子(ローカル変数宣言) – C++11以降は、右辺の式から型を推論する ● autoの推論はCV修飾・参照は消す – decayされる
  • 24.
    auto //cv修飾と参照は消えてしまう inti = 10;//int int& ri = i;//int& auto ai = ri;//int わんくま同盟 大阪勉強会 #61 //cv修飾と参照をつける int i = 10;//int int& ri = i;//int& auto& ai = ri;//int&
  • 25.
    わんくま同盟 大阪勉強会 #61 型推論 - decltype ● autoキーワードとともに追加された型推論の ためのキーワード ● autoの推論はCV修飾・参照は消すがdeclty peでは消されない – そのままの型になる – ただし()で包むと左辺値参照となる
  • 26.
    わんくま同盟 大阪勉強会 #61 decltype int i = 1; decltype(i) d2; //int int& ri = i; decltype(ri) d3 = ri; //int& int&& mi = move(i); decltype(mi) d4 = move(mi); //int&& const int ci = 10; decltype(ci) d5 = ci; //const int
  • 27.
    型推論 - 関数の戻り値の型推論 ● 関数の戻り値の型を推論する – テンプレートなどあらかじめ戻り値の型がわからない ● 関数テンプレートはメタプログラミングやオーバーロードにより、 戻り値の型が型に依存して変わる – 型名が非常に長い ● ラムダ式以外の通常の関数にも関数の戻り 値の推論を広げると、ヒントが欲しい場合が ある わんくま同盟 大阪勉強会 #61 – decltype(auto)
  • 28.
    わんくま同盟 大阪勉強会 #61 Constexpr ● コンパイル時定数式 ● C++11ではconstexpr関数の制約はかなり厳 しかった – 変数宣言ができない – 関数は実質return文一つのみ – 条件分岐は3項演算子のみ – 繰り返しは再帰で表現しなければならない ● C++14ではこれがかなり改善されたがVC++ ではまだ未対応
  • 29.
    わんくま同盟 大阪勉強会 #61 Unicode対応 ● Unicode文字を表現する型としてchar16_tとc har32_tが追加された ● char16_tおよびchar32_tはそれぞれUtf16、 Utf32としてエンコードされるそうです – サロゲートペア・異体字セレクタに関する問題はまだ残っ ている ● リテラルにutf8リテラル、char16_tリテラル、 c har32_tリテラルが追加
  • 30.
    わんくま同盟 大阪勉強会 #61 Unicode //unicode文字 char16_t u16_char = u'a'; char32_t u32_char = U'a'; //unicode文字列 char* u8_char = u8"utf8 string lietral"; char16_t* u16_char = u"utf16 string lietral"; char32_t* u32_char = U"utf32 string lietral"; //std::basic_string<T>のchar16_tとchar32_tに対する特殊化 std::string u8Str = u8"utf8 string"; std::u16string u16Str = u"char16_t string"; std::u32string u32Str = U"char32_t string";
  • 31.
    わんくま同盟 大阪勉強会 #61 生文字列リテラル ● エスケープ不要な文字列リテラル – C#でいう@文字列 ● 書式文字列を使うケースは意外に多いので 使えそうなケースは多いかも //C++14 sprintf(json, R"({"user_id": %d, "name": "%s"})", user_id, name); //C++11以前 sprintf(json, "({"user_id": %d, "name": "%s"})", user_id, name);
  • 32.
    わんくま同盟 大阪勉強会 #61 static_assert ● コンパイル時にアサートをする ● アサートに失敗するとコンパイルが停止する ● type_traitsと組み合させてテンプレートパラ メータの制約チェックに使ったり、コンパイル 時計算の検証に利用する
  • 33.
    わんくま同盟 大阪勉強会 #61 POD型の制約の緩和 ● Cと互換性のあるクラス型をPlain Old Data (POD) と呼ぶ – C++03 におけるルールは必要以上に厳しかった ● POD型であるクラス(構造体) trivial かつsta ndard-layout であり、すべての非静的データ メンバがPOD型である
  • 34.
    わんくま同盟 大阪勉強会 #61 default/delete指定 ● 特殊メンバ関数(コンストラクタ・デストラクタ など)を生成するかどうかを指定することがで きるようになった ● 関数宣言時に= defaultまたはdeleteを指定 する struct X { X() = default; //コンストラクタを生成するように指定する ~X() = default;//デストラクタを生成するように指定する }; struct Y{ Y() = delete;//コンストラクタを生成させない ~Y() = delete;//デストラクタを生成させない };
  • 35.
    わんくま同盟 大阪勉強会 #61 委譲コンストラクタ ● コンストラクタから別のコンストラクタを呼び出 すことができる – これまでのC++はコンストラクタからコンストラクタを呼び 出すことができなかった ● ほかのコンストラクタを別のコンストラクタから 少ない変更で再利用可能になる struct X{ int mValue; //コンストラクタから別のコンストラクタを呼び出す X() : X(0){ } X(int v) :mValue(v) { } };
  • 36.
    わんくま同盟 大阪勉強会 #61 継承コンストラクタ ● 派生クラスにおいて継承元のコンストラクタを 呼び出すことができる ● コンパイラは派生クラスのコンストラクタ呼び 出しを基底クラスのコンストラクタ呼び出しへ と転送するコードを生成する struct Base{ int value; Base(int value) : value(value){} }; struct X : public Base{ // 基底クラスのコンストラクタを派生クラスで使用できるように定義 using Base::Base; };
  • 37.
    強く型付けされた列挙型 ● 列挙型は型安全でなかった – 実質的には整数として扱われているため、型の違う列挙 型の値同士が比較ができてしまう ● 列挙型はスコープを持たない ● C++11ではenum キーワードとclass(struct) キーワードを組み合わせた enum class宣言 を用いることで、型安全でスコープを持つ列 挙型を表現できる わんくま同盟 大阪勉強会 #61
  • 38.
    わんくま同盟 大阪勉強会 #61 明示的な変換関数 ● コンストラクタを暗黙的な型変換関数として扱 われないようにするための修飾子として、exp licitキーワードが導入されている – これは変換関数には効果が無いため暗黙の変換ができ てしまう struct X { X():ptr_(new int()) {} ~X() { delete ptr_; ptr_ = nullptr; } explicit operator bool() { return ptr_ != nullptr; } private: int * ptr_; };
  • 39.
    可変長引数テンプレート ● 可変長のテンプレートパラメータを持つテンプ レートを作成する – std::funciton, std::bind, std::tupleっぽいクラステンプ レートを使おうとすると 引数の数の異なる関数テンプ レート・クラステンプレートを実装する必要があった – 引数の数の異なる関数テンプレート・クラステンプレートを わんくま同盟 大阪勉強会 #61 実装せずに済む
  • 40.
    可変長引数テンプレート template<typename T,typename U> T min(const T& lhs, const U& rhs) { return lhs > rhs ? rhs : lhs; } template<typename T, typename ... U> T min(const T& head, U... tail) { return min(head, min(tail...)); } cout << min(50, 23, 123, 111) << endl; わんくま同盟 大阪勉強会 #61
  • 41.
    わんくま同盟 大阪勉強会 #61 エイリアステンプレート ● using を使ってテンプレートに別名をつける ● テンプレートに対してtypedefを作ることはで きなかった – テンプレートパラメータを指定したものに対しては可能 //typedef と同様の形式 using counter = long; //関数ポインタ using function = void(*)(int); //パラメータを指定したものに別名を付ける using int_vector = vector < int > ; //テンプレートに対して、別名をつける template<class T> using ptr = T*;
  • 42.
    わんくま同盟 大阪勉強会 #61 制限のない共用体 ● 共用体のメンバの制限が取り払われた ● POD型じゃなくても共用体のメンバとすること ができる struct Point{ int x, y; Point(int x1, int y1) :x(x1), y(y1) {} Point operator +(const Point& p) { return Point(x + p.x, y + p.y); } }; union X { int i; double d; Point p; //メンバ関数が定義されていてもunionのメンバとして使用できる };
  • 43.
    わんくま同盟 大阪勉強会 #61 sizeofの拡張 ● 非静的データメンバに対してインスタンス作 成なしにsizeof演算子を適用できる
  • 44.
  • 45.
    わんくま同盟 大阪勉強会 #61 正規表現 std::regex ● <regex>ヘッダが追加 ● 正規表現を使ったパターンマッチングが扱え る – 検索・置換・照合
  • 46.
    Regex 照合 //<で始まって>で終わる文字列にマッチする正規表現で検索 std::regex r("<[^>]+>"); //正規表現にマッチした結果を格納する std::smatch m; string str1 = R"(<html></html>)"; if (regex_match(str1, r)) { cout << "pattern matched" << endl; } else { cout << "pattern matched" << endl; } わんくま同盟 大阪勉強会 #61
  • 47.
    Regex 検索 //<で始まって>で終わる文字列にマッチする正規表現で検索 std::regex r("<[^>]+>"); //正規表現にマッチした結果を格納する std::smatch m; //検索対象の文字列 string str1 = R"(<Window>Hello World</ Window>)"; //検索をするには、regex_searchを使う if (regex_search(str1, m, r)) { cout << "found (pos=" << m.position() << ")" << endl; cout << " ==> " << m.str() << endl; } わんくま同盟 大阪勉強会 #61
  • 48.
    わんくま同盟 大阪勉強会 #61 乱数 ● <random>ヘッダが追加 – 高性能な乱数生成器および分布関数アルゴリズムが数 多く用意されている – メルセンヌツイスタ法 – 一様分布、正規分布、ベルヌーイ分布、サンプリング分布 etc. ● 分野によってはかなり便利そう
  • 49.
    Random - 乱数生成器 //乱数生成器 std::random_device rd; std::mt19937 mt(rd()); for (int i = 0; i < 10; ++i) {   std::cout << mt() << 'n'; } cout << endl; わんくま同盟 大阪勉強会 #61
  • 50.
    わんくま同盟 大阪勉強会 #61 Random 一様分布 std::random_device rd; std::mt19937 mt(rd()); //整数の分布ならstd::uniform_int_distribution std::uniform_int_distribution<int> id(1, 6); //実数の分布ならstd::uniform_real_distribution std::uniform_real_distribution<double> urd(0.0, 10.0); for (int i = 0; i < 10; ++i) { std::cout << id(mt) << 'n'; } for (int i = 0; i < 10; ++i) { std::cout << rd(mt) << 'n'; }
  • 51.
    わんくま同盟 大阪勉強会 #61 Random 正規分布 std::random_device rd; std::mt19937 mt(rd()); //正規分布 std::normal_distribution<> nd(5, 2); std::map<int, int> hist; for (int n = 0; n < 10000; ++n) { ++hist[round(nd(mt))]; } for (auto p : hist) { std::cout << std::fixed << std::setprecision(1) << std::setw(2) << p.first << ' ' << std::string(p.second / 200, '*') << 'n'; }
  • 52.
    わんくま同盟 大阪勉強会 #61 スマートポインタ ● 3種類のスマートポインタが導入された 所有権型のunique_ptr – 参照カウント型のshared_ptr – 弱参照式のweak_ptr ● com_ptr/intrusive_ptr相当は標準にはない のでCOMを使うときはboostintrusive_ptrかa tlbaseのComPtrを使うか自作する必要があ る
  • 53.
    スマートポインタ shared_ptr structX { X() { cout << "call constructor" << endl; } ~X() { cout << "call destructor" << endl; } }; int main() { shared_ptr<X> p; { shared_ptr<X> p1 = shared_ptr<X>(new X()); p = p1; shared_ptr<X> p2 = make_shared<X>(); } わんくま同盟 大阪勉強会 #61 cout << "exit scope" << endl; }
  • 54.
    スマートポインタ unique_ptr structX { X() { cout << "call constructor" << endl; } ~X() { cout << "call destructor" << endl; } }; int main() { unique_ptr<X> p; { unique_ptr<X> p1(new X()); //p = p1; //コピー代入はできないがムーブ代入は可能 p = move(p1); unique_ptr<X> p2(make_unique<X>(); } cout << "exit scope" << endl; } わんくま同盟 大阪勉強会 #61
  • 55.
    わんくま同盟 大阪勉強会 #61 ハッシュテーブル ● <unordered_map><unordered_set>が追加 ● 以前はハッシュテーブルはなかった。 – std::map、std::multimap、std::set、 std::multisetは赤 黒木で実装されておりこれは2分探索木なのでハッシュで はない ● ハッシュテーブルとして,std::unordered_ma p, std::unordered_setが追加された
  • 56.
    わんくま同盟 大阪勉強会 #61 thread ● <thread>が追加 ● 関数、メンバ関数、ラムダ式などからスレッド オブジェクトを生成する – 機能としてはかなりプリミティブ – 環境独自のAPIを呼ぶ必要がなくなる ● 移植性の向上
  • 57.
    Thread 関数からスレッドオブジェクトを作る voiddo_work1() { for (auto i = 0; i < 10; ++i) cout << "working1 n"; } //関数からスレッドオブジェクトを生成 thread th1(do_work1); わんくま同盟 大阪勉強会 #61 //待機 th1.join();
  • 58.
    わんくま同盟 大阪勉強会 #61 Filesystem v3 ● <filesystem>が追加 – C++1z(C++17)に導入予定だが先取りで入ってる – std::tr2::sys 名前空間が提供されている ● OSの違いを気にすることなくファイル・ディレ クトリを扱うことができる – 環境独自のAPIを呼ぶ必要がなくなる ● 移植性の向上
  • 59.
    Filesystem 移動とコピー //ファイルのコピー const fs::path path("dir1/a.txt"); // コピ const fs::path dest("dir2/a.txt"); // コピー先 try { fs::copy_file(path, dest); } catch (fs::filesystem_error& ex) { std::cout << ex.what() << std::endl; } わんくま同盟 大阪勉強会 #61 //ファイルの移動 const fs::path path("dir1/a.txt"); const fs::path dest("dir2/b.txt"); try { fs::rename(path, dest); } catch (fs::filesystem_error& ex) { std::cout << ex.what() << std::endl; }
  • 60.
    Filesystem ファイルサイズの取得と存在チェック //ファイルの存在チェック const fs::path path("dir1/a.txt"); std::error_code error; const bool result = fs::exists(path, error); if (!result || error) { std::cout << "ファイルがない" << std::endl; } else { std::cout << "ファイルがあった" << std::endl; } //ファイルサイズを取得する const fs::path path("dir1/a.txt"); try { const auto size = fs::file_size(path); std::cout << "ファイルサイズ: " << size << std::endl; } catch (fs::filesystem_error& ex) { std::cout << ex.what() << std::endl; } わんくま同盟 大阪勉強会 #61
  • 61.
    わんくま同盟 大阪勉強会 #61 chrono ● <chrono>ヘッダが追加 – std::chrono名前空間が提供されている ● 時間に関するユーティリティとして機能する関 数・クラスを提供 – 時間単位の変換 – 経過時間の測定
  • 62.
    std::chronoによる処理時間の計測 //処理開始時刻 autostart = std::chrono::system_clock::now(); // 重たーい処理 auto j = 0UL; for (auto i = 1UL; i <= 100000000; ++i) { j += i; } //処理終了時刻 auto end = std::chrono::system_clock::now(); // 終了時刻と開始時刻の差分 auto diff = end - start; std::cout << "elapsed time = " //millisec単位に変換 << std::chrono::duration_cast<std::chrono::milliseconds>(diff).count() << " msec." << std::endl; わんくま同盟 大阪勉強会 #61
  • 63.
    わんくま同盟 大阪勉強会 #61 まとめ ● VC++についてお話しました – 今回お話ししたのはほんの一部です。色々楽しい機能が 追加されているので是非遊んでみてください – C++界隈ではなにかといわれるMSVCですが、標準対応 は結構がんばっていると思います – VS2015のリリース版には入ってほしいなぁ
  • 64.
    わんくま同盟 大阪勉強会 #61 次に発表したいこと ● C++AMP ● 音声合成・音声認識
  • 65.
    わんくま同盟 大阪勉強会 #61 参考文献 ● ISO C++ ● VC++ Team Blog ● MSDN ● 本の虫.江添亮のブログ ● Faith and Brave C++で遊ぼう ● Cpprefjp ● C++ポケットリファレンス
  • 66.