C++111. C++11 is 何?
C++11 でできること
.
...... C++11
hatsusato
京都大学理学部 1 回
2012 年 12 月 20 日
hatsusato C++11
4. C++11 is 何?
C++11 でできること
.. 自己紹介
@hatsusato のプロフィール
C++一筋
理学部数学系志望
hatsusato C++11
5. C++11 is 何?
C++11 でできること
.. 自己紹介
@hatsusato のプロフィール
C++一筋
理学部数学系志望
大学院は情報の流れ濃厚
hatsusato C++11
6. C++11 is 何?
C++11 でできること
.. 自己紹介
@hatsusato のプロフィール
C++一筋
理学部数学系志望
大学院は情報の流れ濃厚
げんごつくる
hatsusato C++11
9. C++11 is 何?
C++11 でできること
.. C++11 is 何?
C++11 とは、2011 年に標準化された C++の最新規格の
ことである。
hatsusato C++11
10. C++11 is 何?
C++11 でできること
.. C++11 is 何?
C++11 とは、2011 年に標準化された C++の最新規格の
ことである。
それまでの C++03 とは比べ物にならないほどまともに
なった。これで一人前の言語に。
hatsusato C++11
11. C++11 is 何?
C++11 でできること
.. C++11 is 何?
C++11 とは、2011 年に標準化された C++の最新規格の
ことである。
それまでの C++03 とは比べ物にならないほどまともに
なった。これで一人前の言語に。
コア言語の機能が拡張され、今までに出来なかったり、
面倒くさい遠回りをして実現していたたくさんのことが
簡単にできるように。
hatsusato C++11
12. C++11 is 何?
C++11 でできること
.. C++11 is 何?
C++11 とは、2011 年に標準化された C++の最新規格の
ことである。
それまでの C++03 とは比べ物にならないほどまともに
なった。これで一人前の言語に。
コア言語の機能が拡張され、今までに出来なかったり、
面倒くさい遠回りをして実現していたたくさんのことが
簡単にできるように。
標準ライブラリも大きく拡充され、たくさんの便利なラ
イブラリが簡単に利用できるように。
hatsusato C++11
13. C++11 is 何?
C++11 でできること
.. C++11 is 何?
C++11 とは、2011 年に標準化された C++の最新規格の
ことである。
それまでの C++03 とは比べ物にならないほどまともに
なった。これで一人前の言語に。
コア言語の機能が拡張され、今までに出来なかったり、
面倒くさい遠回りをして実現していたたくさんのことが
簡単にできるように。
標準ライブラリも大きく拡充され、たくさんの便利なラ
イブラリが簡単に利用できるように。
それでいて実行時速度は変わらないか、むしろ速く
なった。
hatsusato C++11
14. C++11 is 何?
C++11 でできること
.. C++11 is 何?
C++11 とは、2011 年に標準化された C++の最新規格の
ことである。
それまでの C++03 とは比べ物にならないほどまともに
なった。これで一人前の言語に。
コア言語の機能が拡張され、今までに出来なかったり、
面倒くさい遠回りをして実現していたたくさんのことが
簡単にできるように。
標準ライブラリも大きく拡充され、たくさんの便利なラ
イブラリが簡単に利用できるように。
それでいて実行時速度は変わらないか、むしろ速く
なった。
要するに C++11 最高。
hatsusato C++11
15. C++11 is 何?
C++11 でできること
.. C++11 でできること
auto
range-based for
initializer list
nullptr
lambda expression
move semantics
constexpr
useful and powerful libraries
時間の都合により割愛します。
and more!
hatsusato C++11
17. C++11 is 何?
C++11 でできること
.. auto
.
これまで
..
......
for(std :: vector <std ::pair <std:: string ,std :: string > >::
const_iterator it=v.begin (); it!=v.end (); ++it){
// do something.
}
変数を初期化する際には、必ず変数の型を明示的に指定
する必要があるが、時には複雑な型名を書かなければな
らないことがある。
特にテンプレートが絡むと、右辺の式の型がどんな型に
なるのかを知ることが困難になることがある。
しかし、いずれにせよ右辺の式の型は一意に定まるので
変数の型は自明である。
hatsusato C++11
18. C++11 is 何?
C++11 でできること
.. auto
.
これから
..
......
for(auto it=std :: begin(v); it!= std :: end(v); ++it){
// do something.
}
C++は型推論を手に入れた!
コンパイラは右辺の式の型を知っているので、自動的に
auto を右辺の式の型に置き換えてくれる。
素人から玄人まで、誰でも簡単に使えて誰でも利益を享
受できるので、どんどん使いましょう。
hatsusato C++11
19. C++11 is 何?
C++11 でできること
.. auto
.
これまで
..
......
for(std :: vector <std ::pair <std:: string ,std :: string > >::
const_iterator it=v.begin (); it!=v.end (); ++it){
// do something.
}
.
これから
..
......
for(auto it=std :: begin(v); it!= std :: end(v); ++it){
// do something.
}
hatsusato C++11
21. C++11 is 何?
C++11 でできること
.. range-based for
.
これまで
..
......
for(std :: vector <std ::string >:: const_iterator vit=v.begin
(); vit !=v.end (); ++vit){
for(std :: string :: const_iterator sit=vit ->begin (); sit!=
vit ->end (); ++ sit ){
// do something.
}
}
コンテナ内の全要素を走査するといったことは頻繁に起
こるが、そのたびにイテレータを作る必要があり、可読
性の低いコードになってしまう。
イテレータはポインタのようなものなので、いちいち間
接参照する必要がある。コンテナのコンテナを走査した
りすると可読性を著しく損なう。
hatsusato C++11
22. C++11 is 何?
C++11 でできること
.. range-based for
.
これから
..
......
for(auto vx : v){
for(auto sx : vx){
// do something.
}
}
コンテナの全要素を走査したい時であれば、いちいちイ
テレータを作る必要がなくなった。前述の auto を併用す
ることでコンテナの要素の型を指定する必要もない。
コンテナの各要素を参照で受け取れるので、イテレータ
の時と違って間接参照する必要がなく、コンテナのコン
テナの走査も難なく書ける。
これも簡単に使えるのでどんどん使いましょう。
hatsusato C++11
23. C++11 is 何?
C++11 でできること
.. range-based for
.
これまで
..
......
for(std :: vector <std ::string >:: const_iterator vit=v.begin
(); vit !=v.end (); ++vit){
for(std :: string :: const_iterator sit=vit ->begin (); sit!=
vit ->end (); ++ sit ){
// do something.
}
}
.
これから
..
......
for(auto vx : v){
for(auto sx : vx){
// do something.
}
}
hatsusato C++11
25. C++11 is 何?
C++11 でできること
.. initializer list
.
これまで
..
......
int tmp []={13 ,22 ,37 ,41 ,58};
std :: vector <int > v(tmp ,tmp +5);
// vに13 ,22 ,37 ,41 ,58 を 格 納 す る 。
v.clear ();
v.push_back (13);
v.push_back (22);
v.push_back (37);
v.push_back (41);
v.push_back (58);
// vに13 ,22 ,37 ,41 ,58 を 格 納 し な お す 。
コンテナをいくつかのデータで初期化するためには、現
状では上記のように一時的に配列を作ったり、push back
を並べたりする必要があり、可読性があまりよくない。
hatsusato C++11
26. C++11 is 何?
C++11 でできること
.. initializer list
.
これから
..
......
std :: vector <int > v={13 ,22 ,37 ,41 ,58};
可読性がよい。
従来の構造体や配列の初期化と同じ構文であり、また通
常のコンストラクタも {} で呼び出せるようになったの
で、「初期化は {}、関数呼び出しは ()」というように役
割分担することでコードがより明確になる。
変数の初期化の場面で {} をどんどん使いましょう。
hatsusato C++11
27. C++11 is 何?
C++11 でできること
.. initializer list
.
これまで
..
......
int tmp []={13 ,22 ,37 ,41 ,58};
std :: vector <int > v(tmp ,tmp +5);
// vに13 ,22 ,37 ,41 ,58 を 格 納 す る 。
v.clear ();
v.push_back (13);
v.push_back (22);
v.push_back (37);
v.push_back (41);
v.push_back (58);
// vに13 ,22 ,37 ,41 ,58 を 格 納 し な お す 。
.
これから
..
......
std :: vector <int > v={13 ,22 ,37 ,41 ,58};
hatsusato C++11
29. C++11 is 何?
C++11 でできること
.. nullptr
.
これまで
..
......
// 関 数 オ ー バ ー ロ ー ド
void f(int ){ std ::cout <<"f(int)"<<std :: endl ;}
void f(int *){ std ::cout <<"f(int *)"<<std :: endl ;}
f(NULL ); // コ ン パ イ ル エ ラ ー : 曖 昧 な オ ー バ ー ロ ー ド
そもそも C では
#define NULL ((void*)0)
となっているが、C++では (void*) から任意のポインタ
への暗黙変換ができない。そのため、C++11 以前では
#define NULL 0
となっていた。よって、NULL を数値の (int)0 と解釈す
べきか、ヌルポインタの (int*)0 と解釈すべきか曖昧に
なってしまう。
hatsusato C++11
30. C++11 is 何?
C++11 でできること
.. nullptr
.
これから
..
......
// 関 数 オ ー バ ー ロ ー ド
void f(int ){ std ::cout <<"f(int)"<<std :: endl ;}
void f(int *){ std ::cout <<"f(int *)"<<std :: endl ;}
f(nullptr ); // > f(int *)
C++11 からは任意のポインタへ暗黙変換可能な
nullptr t 型のキーワード nullptr が追加され、ややこ
しい問題はなくなった。
もはや NULL を使う意味はありません。ヌルポインタを使
いたいところには nullptr を使いましょう。
hatsusato C++11
31. C++11 is 何?
C++11 でできること
.. nullptr
.
関数定義
..
......
// 関 数 オ ー バ ー ロ ー ド
void f(int ){ std ::cout <<"f(int)"<<std :: endl ;}
void f(int *){ std ::cout <<"f(int *)"<<std :: endl ;}
.
これまで
..
......
f(NULL ); // コ ン パ イ ル エ ラ ー : 曖 昧 な オ ー バ ー ロ ー ド
.
これから
..
......
f(nullptr ); // > f(int *)
hatsusato C++11
33. C++11 is 何?
C++11 でできること
.. lambda expression
.
これまで
..
......
struct AbsoluteLess {
bool operator ()( int lhs , int rhs){
return std :: abs(lhs)<std :: abs(rhs );
}
};
std :: sort(v.begin (), v.end(), AbsoluteLess ());
// 絶 対 値 の 大 小 で ソ ー ト
C++11 以前はアルゴリズムごとに関数や関数オブジェク
トを作る必要があった。たとえ一度きりしか使わないア
ルゴリズムであってもいちいち関数(オブジェクト)を
作っていたが、この方法は記述量が多く、コードの流れ
がわかりづらい。また、名前空間中に余分な名前があふ
れることにつながる。
hatsusato C++11
34. C++11 is 何?
C++11 でできること
.. lambda expression
.
これから
..
......
std :: sort(std :: begin(v), std ::end(v),
[]( int lhs , int rhs)->bool
{return std ::abs(lhs)<std:: abs(rhs );});
ラムダ式の登場により、アルゴリズムを表す関数(オブ
ジェクト)を作る代わりにラムダ式(つまり無名関数オ
ブジェクト)で代用できるようになった。これにより余
分な名前が名前空間にはびこることなくコードをすっき
りと書くことができるようになった。
hatsusato C++11
35. C++11 is 何?
C++11 でできること
.. lambda expression
.
これまで
..
......
struct AbsoluteLess {
bool operator ()( int lhs , int rhs){
return std :: abs(lhs)<std :: abs(rhs );
}
};
std :: sort(v.begin (), v.end(), AbsoluteLess ());
// 絶 対 値 の 大 小 で ソ ー ト
.
これから
..
......
std :: sort(std :: begin(v), std ::end(v),
[]( int lhs , int rhs)->bool
{return std ::abs(lhs)<std:: abs(rhs );});
hatsusato C++11
37. C++11 is 何?
C++11 でできること
.. move semantics
.
MyString クラス
..
......
class MyString{
char* _data;
size_t _size;
public:
MyString(const MyString& str) // copy constructor
:_data(new char[str._size ]), _size(str._size ){
std:: copy(str._data , str._data+_size , _data );
}
MyString(MyString && str) // move constructor
:_data(str._data), _size(str._size ){
str._data=nullptr;
str._size =0;
}
// other functions ...
};
hatsusato C++11
38. C++11 is 何?
C++11 でできること
.. move semantics
.
これまで
..
......
MyString :: MyString(const MyString& str)
:_data(new char[str._size ]), _size(str._size ){
std :: copy(str._data , str._data+_size , _data );
}
C++11 以前はデータの複製を作る際には、いたる所でコ
ピーが行われていた。それが当たり前だった。
hatsusato C++11
39. C++11 is 何?
C++11 でできること
.. move semantics
.
これから
..
......
MyString :: MyString(MyString && str)
:_data(str._data), _size(str._size ){
str._data=nullptr;
str._size =0;
}
C++11 では右辺値参照という概念が追加され、より効率
のよいデータの複製方法が提供されるようになった。
関数の戻り値などの、代入することのできないオブジェ
クトを右辺値と呼ぶ。move とは右辺値を複製する際に
コピーをせず、ポインタの付け替えなどによってデータ
を移譲する技術のことである。
hatsusato C++11
40. C++11 is 何?
C++11 でできること
.. move semantics
.
これから
..
......
MyString :: MyString(MyString && str)
:_data(str._data), _size(str._size ){
str._data=nullptr;
str._size =0;
}
move は主にユーザコード側ではなくライブラリ提供側
が利用する技術なので、ユーザコードを特に変更するこ
となく恩恵を受けられる。
STL などの右辺値参照に対応したライブラリを用いた
コードの実行時速度が、C++11 としてコンパイルするだ
けで、知らず知らずのうちに向上する。
move semantics 素晴らしい。
hatsusato C++11
42. C++11 is 何?
C++11 でできること
.. constexpr
.
これまで
..
......
#define CUBE(x) (x*x*x)
#define SIDE_SIZE (10)
#define ARRAY_SIZE (CUBE(SIDE_SIZE ))
double array[ARRAY_SIZE ]; // 10^3 個 の 値 を 格 納 す る 配 列
C++11 以前は、配列の要素数として使えるのは、整数定
数または整数定数で初期化された const な変数と整数定
数で#define したシンボルのみであった。
定数から計算して得られる結果は定数では無いので、そ
の結果を const 変数に代入しても、配列の要素数として
は使えない。
かわりに上記のようにして表現することは出来るが、
#define は型安全では無いので、C++において使うのは
できるだけ避けるべきである。
hatsusato C++11
43. C++11 is 何?
C++11 でできること
.. constexpr
.
これから
..
......
constexpr int Cube(int x){ return x*x*x;}
constexpr int SIDE_SIZE =10;
constexpr int ARRAY_SIZE=Cube(SIDE_SIZE );
double array[ARRAY_SIZE ]; // 10^3 個 の 値 を 格 納 す る 配 列
C++11 から constexpr というキーワードが追加され、コ
ンパイル時定数とコンパイル時関数を定義することがで
きるようになった。
コンパイル時定数にはコンパイル時に決定可能な値を指
定することができ、コンパイル時にその値に置き換えら
れる。
hatsusato C++11
44. C++11 is 何?
C++11 でできること
.. constexpr
.
これから
..
......
constexpr int Cube(int x){ return x*x*x;}
constexpr int SIDE_SIZE =10;
constexpr int ARRAY_SIZE=Cube(SIDE_SIZE );
double array[ARRAY_SIZE ]; // 10^3 個 の 値 を 格 納 す る 配 列
コンパイル時関数は関数内で記述できる処理が制限され
ているものの、全ての引数がコンパイル時定数ならば戻
り値がコンパイル時に計算され、コンパイル時定数や
const 定数の初期化に使うことができる。引数の一部が
実行時に決定される場合は、コンパイルエラーになるこ
となく、実行時に計算される。
上記のようにコンパイル時関数には戻り値の型があり、
型安全である。
hatsusato C++11
45. C++11 is 何?
C++11 でできること
.. 便利なライブラリ群
スマートポインタ (shared ptr, weak ptr, unique ptr)
擬似乱数生成 (メルセンヌツイスタなど)
正規表現
ハッシュ表 (unordered map, unordered set)
スレッドライブラリ
その他たくさんの便利機能追加修正
またの機会に。
hatsusato C++11
47. C++11 is 何?
C++11 でできること
.. C++11 の利用方法
C++11 はつい最近確定したばかりの巨大な規格なので、
C++11 対応したコンパイラはまだ少ないのが現状です。
hatsusato C++11
48. C++11 is 何?
C++11 でできること
.. C++11 の利用方法
C++11 はつい最近確定したばかりの巨大な規格なので、
C++11 対応したコンパイラはまだ少ないのが現状です。
例えば gcc では、gcc4.3 以降で-std=c++11 オプション
(-std=c++11 の c は小文字なので注意)を指定すること
で C++11 のコードとしてコンパイルできるようになって
います。
hatsusato C++11
49. C++11 is 何?
C++11 でできること
.. C++11 の利用方法
C++11 はつい最近確定したばかりの巨大な規格なので、
C++11 対応したコンパイラはまだ少ないのが現状です。
例えば gcc では、gcc4.3 以降で-std=c++11 オプション
(-std=c++11 の c は小文字なので注意)を指定すること
で C++11 のコードとしてコンパイルできるようになって
います。
ちなみに今回のスライドのコードスニペットは gcc
version 4.7.2 で実行確認しました。
hatsusato C++11
50. C++11 is 何?
C++11 でできること
.. C++11 の利用方法
C++11 はつい最近確定したばかりの巨大な規格なので、
C++11 対応したコンパイラはまだ少ないのが現状です。
例えば gcc では、gcc4.3 以降で-std=c++11 オプション
(-std=c++11 の c は小文字なので注意)を指定すること
で C++11 のコードとしてコンパイルできるようになって
います。
ちなみに今回のスライドのコードスニペットは gcc
version 4.7.2 で実行確認しました。
もはや C++03 でコードを書くことは大きな損失に他なり
ません。これから C++を使うときは是非 C++11 を使い
ましょう。
hatsusato C++11
51. C++11 is 何?
C++11 でできること
.. まとめ
C++11 は書きやすく、読みやすく、また速いコードを簡
単に書くことができる!素晴らしい!
hatsusato C++11
52. C++11 is 何?
C++11 でできること
.. 訂正
//do something. の部分で v に対して変更を加えないのであ
れば、auto ではなくて、const auto であるべき。
.
auto
..
......
for(const auto it=std:: begin(v); it!=std:: end(v); ++it){
// do something.
}
.
range-based for
..
......
for(const auto& vx : v){
for(const auto& sx : vx){
// do something.
}
}
hatsusato C++11