#topicpath ////////////////////////////////////////////////////////////////////////////// * 目次 [#pa168adc] #contents(); ////////////////////////////////////////////////////////////////////////////// * C++11 のキーワード (取り敢えず関心のあるものだけ) [#m4713ac6] //============================================================================ ** スコープ付き enum [#enum-class] - 他の enum で定義された名前と重複しても識別できるようになる - enum をスコープ付きにするには、 ''enum'' に続いて ''struct'' または ''class'' 修飾子を付ける。 -- ここでの struct と class には、特に違いはない enum class COMMAND { IDLE, START, STOP, }; int foo() { COMMAND cmd = COMMAND::IDLE; // スコープ付きで定義した enum 値は、スコープが必要になる。 ... } //============================================================================ ** enum の基礎型の指定 [#enum-base-type] - 特に指定しない場合、スコープ付き列挙型では、int がベースとなる。 - 他の型をベースにしたい場合は、以下のように指定する: // int ではなく unsigned int を指定する場合 enum class COMMAND : unsigned int { IDLE, START, STOP, }; //============================================================================ ** アライメントの指定 [#vb8529d6] //============================================================================ ** std::nullptr [#lb7c9c62] //============================================================================ ** 参照修飾子 [#re106fd3] //============================================================================ ** 移譲/継承 コンストラクタ [#rd52b5a3] //============================================================================ ** explicit な型変換演算子 [#o4c7c9aa] //============================================================================ ** ラムダ式 [#lambda] [キャプチャ] (仮引数リスト) -> 戻り値の型 { 関数の中身 }; - キャプチャ -- ラムダ式から参照するオブジェクトを指定。ラムダ式の定義されたスコープにあるオブジェクトのうちでラムダ式が参照できるのは、キャプチャで指定されたものに限られる。 -- キャプチャは以下の2種類がある --- 参照キャプチャ:オブジェクトが参照で渡される --- コピーキャプチャ:実体のコピーが渡される -- 記述方法 |~記述 |~意味 | |[=] |全てをコピーキャプチャ。メンバ関数内の場合は this も対象となる | |[&] |全てを参照キャプチャ | |[hoge] |オブジェクト hoge をコピーキャプチャ | |[&hoge] |オブジェクト hoge を参照キャプチャ | |[=, &hoge] |オブジェクト hoge を参照キャプチャ、それ以外はコピーキャプチャ | |[&, hoge] |オブジェクト hoge をコピーキャプチャ、それ以外は参照キャプチャ | - 戻り値型には auto を指定することが出来る //============================================================================ ** 属性 [#we1705b4] - noreturn -- 呼び出しても戻ってこない関数の記述に使用する [[ noreturn ]] void f(); -- noreturn 属性を指定された関数が throw を送出すれば、その関数から「戻る」ことが可能。 -- noreturn 属性を指定された関数が return 文を実行したり、関数末尾に到達して呼び出し元に戻った場合の挙動は未定義。 - carries_dependency -- 関数間でデータの依存性を伝播するために使用する -- ''詳細は要確認'' //============================================================================ ** 例外 [#w63a2c53] *** 例外クラスの使い分け [#kb44dcdd] *** 例外を送出しないことを明示する [#l975009b] *** 例外ポインタ [#b703371f] *** 入れ子の例外関連 [#if27cf02] //============================================================================ ** std::sto* --- 文字列を数値に変換する [#sto] int std::stoi( const string& str, size_t* idx = 0, int base = 10 ); int std::stoi( const wstring& str, size_t* idx = 0, int base = 10 ); long std::stol( const string& str, size_t* idx = 0, int base = 10 ); long std::stol( const wstring& str, size_t* idx = 0, int base = 10 ); unsigned long std::stoul( const string& str, size_t* idx = 0, int base = 10 ); unsigned long std::stoul( const wstring& str, size_t* idx = 0, int base = 10 ); long long std::stoll( const string& str, size_t* idx = 0, int base = 10 ); long long std::stoll( const wstring& str, size_t* idx = 0, int base = 10 ); unsigned long long std::stoull( const string& str, size_t* idx = 0, int base = 10 ); unsigned long long std::stoull( const wstring& str, size_t* idx = 0, int base = 10 ); float std::stof( const string& str, size_t* idx = 0 ); float std::stof( const wstring& str, size_t* idx = 0 ); double std::stod( const string& str, size_t* idx = 0 ); double std::stod( const wstring& str, size_t* idx = 0 ); long double std::stold( const string& str, size_t* idx = 0 ); long double std::stold( const wstring& str, size_t* idx = 0 ); //============================================================================ ** std::to_string --- 数値を文字列に変換する [#to_string] #include <string> std::string std::to_string( int val ); std::string std::to_string( unsigned int val ); std::string std::to_string( long val ); std::string std::to_string( unsigned long val ); std::string std::to_string( long long val ); std::string std::to_string( unsigned long long val ); std::string std::to_string( float val ); std::string std::to_string( double val ); std::string std::to_string( long double val ); std::wstring std::to_wstring( int val ); std::wstring std::to_wstring( unsigned int val ); std::wstring std::to_wstring( long val ); std::wstring std::to_wstring( unsigned long val ); std::wstring std::to_wstring( long long val ); std::wstring std::to_wstring( unsigned long long val ); std::wstring std::to_wstring( float val ); std::wstring std::to_wstring( double val ); std::wstring std::to_wstring( long double val ); //============================================================================ ** 正規表現での検索 [#ff98d5c1] - regex は g++4.7 では未実装なので動作しない(4.9で実装済みらしい)~ → [[Bug 53631 - [C++11] <regex> is unimplemented>https://gcc.gnu.org/bugzilla/show_bug.cgi?id=53631]] //============================================================================ ** 浮動小数点数の入力 [#o476bddb] //============================================================================ ** 日付・時刻 [#o44a5361] - #include <iomanip> //============================================================================ ** 乱数生成 [#mc805a6d] - #include <random> //============================================================================ ** shared_ptr (共有ポインタ) [#shared_ptr] - std::shared_ptr - #include <memory> - 通常のポインタ同様の操作が出来る - 複数の std::shared_ptr が1つのリソースを指し示すことが出来る - 同じリソースを参照する std::shred_ptr が1つもなくなった時、そのリソースは自動的に開放される - 書式 T : shared_ptrとして使用したいclassの型とする std::shared_ptr<T> 変数名( new T() [, reset_function] ); - 例 #include <iostream> #include <memory> #include "ClassA.h" using namespace std; int main( int argc, char* argv[] ) { shared_ptr<ClassA> sp1( new ClassA ); // new したポインタから shared_ptr を構築 { shared_ptr<ClassA> sp2 = sp1; // 2つの shared_ptr で1個のリソースを参照する sp2->foo(); } // ここで sp2 が破棄され、参照している shared_ptr が1個になる sp1->foo(); // 同じ実体の foo() の2回目の呼び出し sp1->bar(); return( 0 ); } //---------------------------------------------------------------------------- *** リソース開放時の処理の指定 [#l47120f9] - リソースを開放するときの処理を指定することが出来る。 std::shared_ptr<T> 変数名( new T() [, reset_function] ); の reset_function に、リソース開放処理を行う関数を渡す。 - 例: void custom_reset( FILE * pf ) { if( pf ) { fclose( pf ); pf = NULL; } } int main( int argc, char * argv[] ) { std::shared_ptr<FILE> sp_f( fopen( "file.txt", "+w" ), custom_reset ); ... return( 0 ); } //---------------------------------------------------------------------------- *** std::shared_ptr::get() --- 組み込みポインタの取得 [#z3882f41] std::shared_ptr<ClassA> up_a1; ClassA *p_a1 = up_a1.get(); // up_a1 が持っている ClassA のリソースを指す組み込みポインタを取得 //---------------------------------------------------------------------------- *** std::make_shared() --- std::shared_ptr 構築のためのヘルパ関数 [#k8ecea9f] - この関数は内部で new を行なっており、リソース構築に失敗した場合にリソースリークを起こさない特性を持っている。 - 例 class X { public: X( int i, std::string str ) { m_i = i; m_str = str; } private: int m_i; string m_str; }; int main( int argc, char * argv[] ) { std::shared_ptr<X> px = std::make_shared<X>( 10, "aaa" ); ... return( 0 ); } //============================================================================ ** unique_ptr [#unique_ptr] - std::unique_ptr - #include <memory> - std::shared_ptr と同様、リソースをデストラクタによって自動的に開放させるための class - ''コピーが出来ないようになっているため、リソースを参照しているオブジェクトが1つであることが保証される'' - C++03 までは std::auto_ptr があったが、C++11 では非推奨になった。 - 書式 std::unique_ptr<unique_ptrとして使用したいclassの型> 変数名 - 例 #include <memory> class ClassX { public: ClassX() { m_count_foo = 0; }; virtual ~ClassX() { std::cout << "Destroyed" << std::endl; }; void foo() { m_count_foo++; std::cout << "Execute foo(): " << m_count_foo << std::endl; } private: int m_count_foo; }; // 参照する unique_ptr を変更する void swap_unique_ptr( unique_ptr<ClassX> &up_src, unique_ptr<ClassX> &up_dst ) { up_dst = move( up_src ); cout << "unique_ptr is moved up_src to up_dst" << endl; } int main( int argc, char* argv[] ) { unique_ptr<ClassX> up1( new ClassX ); // ↓ unique_ptr は複数箇所から参照できない。これを書くとエラーになる // unique_ptr<ClassX> up2 = up1; up1->foo(); unique_ptr<ClassX> up2; swap_unique_ptr( up1, up2 ); up2->foo(); up2 = nullptr; // これを実行した時点でリソースが開放される cout << "Terminate Program" << endl; return( 0 ); } //---------------------------------------------------------------------------- *** std::move() --- unique_ptr の移動 [#xe4070f7] - リソースを参照するオブジェクトを変更するには、 std::move() を使用する。 std::unique_ptr std::move( std::unique_ptr src ); //---------------------------------------------------------------------------- *** std::unique_ptr::get() --- 組み込みポインタの取得 [#z3882f41] std::unique_ptr<ClassX> up_x1; ClassX *p_x1 = up_x1.get(); // up_x1 が持っている ClassX のリソースを指す組み込みポインタを取得 //============================================================================ ** 複数の値から、最大値または最小値を選択する [#hfd09405] //============================================================================ ** 2つの変数を入れ替える [#s458c40d] //============================================================================ ** コンパイル時にアサーションを行う [#db4bc5bc] //============================================================================ ** 浮動小数点数の四捨五入 [#a44e97e9] //============================================================================ ** 数学関数 [#b2da218a] //============================================================================ ** std::function --- 関数オブジェクトを変数に持つ [#std-function] - #include <functional> - std::function - 関数オブジェクトや関数ポインタを変数として保持するために使用する class - 書式 戻り値型( 実引数型1, 実引数型2, ... 実引数型N ); - 例 struct ST_FOO { int operator() ( int x, int y ) const { return( x + y ); } }; int bar( int x, int y ) { return( x * y ); } // 構造体 std::function<int (int, int)> f = ST_FOO(); // 関数 std::function<int (int, int)> g = bar; // λ関数 std::function<int (int, int)> h = []( int x, int y ) -> int { return( x - y ); }; int result_f = f( 1, 2 ); std::cout << "f: " << result_f << std::endl; int result_g = g( 3, 4 ); std::cout << "g: " << result_g << std::endl; int result_h = h( 6, 5 ); std::cout << "h: " << result_h << std::endl; //============================================================================ ** 時間演算を行う [#j45d63eb] - #include <chrono> //============================================================================ ** タプル [#g6c7a34b] - #include <tuple> - 複数の異なる型の値の集合体 std::tuple<TYPE1, TYPE2,...> value(val1, val2,...); - 例 #include <iostream> #include <string> #include <tuple> using namespace std; void print_tuple( tuple<int, char, string> &t ) { cout << "1:[" << get<0>( t ) << "] 2:[" << get<1>( t ) << "] 3:[" << get<2>( t ) << "]" << endl; } int main( int argc, char * argv[] ) { tuple<int, char, string> t( 1, 'a', "Hello" ); // 値を参照する print_tuple( t ); // まとめて値を設定する t = make_tuple( 2, 'b', "World" ); // 再び値を参照する print_tuple( t ); return( 0 ); } //============================================================================ ** システム終了 [#gf1533a6] //============================================================================ ** スレッド [#thread] - → [[Lang/C++/C++11/thread]] //============================================================================ ** コンテナ [#container] - → [[Lang/C++/C++11/コンテナ]] ////////////////////////////////////////////////////////////////////////////// * build (clang++/g++) [#r110442c] - コンパイラオプションに "-std=c++11" または "-std=c++0x" の追加が必要となる場合がある -- 指定し忘れた場合、以下のように本来あるはずの定義がないと怒られる: [例] clang++ の場合:shared_ptr が std に存在しないという下記のエラーが出る: clang++ -Wall -ggdb -c -o custom_deletee.o custom_deletee.C custom_deletee.C:46:8: error: no member named 'shared_ptr' in namespace 'std' std::shared_ptr<CX> spx1( new CX( 11, (char *)"test-BBBB" ), FinalizeCX ); ~~~~~^