C++11 のキーワード (取り敢えず関心のあるものだけ)†
スコープ付き enum†
- 他の enum で定義された名前と重複しても識別できるようになる
- enum をスコープ付きにするには、 enum に続いて struct または class 修飾子を付ける。
- ここでの struct と class には、特に違いはない
enum class COMMAND {
IDLE,
START,
STOP,
};
int foo()
{
COMMAND cmd = COMMAND::IDLE; // スコープ付きで定義した enum 値は、スコープが必要になる。
...
}
enum の基礎型の指定†
for 文(範囲指定)†
- 書式
std::vector<int> vec = { 1, 3, 6, 7, 11, 32, 64 };
for( int val : vec ) {
// 処理
}
- この書式は以下に対して使用出来る
- 標準ライブラリのコンテナのように、begin(), end() を持つ
- begin(), end() の非メンバ関数を使うことが出来る
for_each†
#include <vector> // for std::vector
#include <algorithm> // for std::for_each
std::vector<int> v = { 1, 2, 3, 4 };
std::for_each( v.begin(), v.end(), [](int& n) { m *= 5; } );
アライメントの指定†
std::nullptr†
参照修飾子†
移譲/継承 コンストラクタ†
explicit な型変換演算子†
ラムダ式†
[キャプチャ] (仮引数リスト) -> 戻り値の型 { 関数の中身 };
- キャプチャ
- ラムダ式から参照するオブジェクトを指定。ラムダ式の定義されたスコープにあるオブジェクトのうちでラムダ式が参照できるのは、キャプチャで指定されたものに限られる。
- キャプチャは以下の2種類がある
- 参照キャプチャ:オブジェクトが参照で渡される
- コピーキャプチャ:実体のコピーが渡される
- 記述方法
記述 | 意味 | 備考 |
[=] | 全てをコピーキャプチャ。メンバ関数内の場合は this も対象となる | |
[&] | 全てを参照キャプチャ | |
[hoge] | オブジェクト hoge をコピーキャプチャ | |
[&hoge] | オブジェクト hoge を参照キャプチャ | |
[=, &hoge] | オブジェクト hoge を参照キャプチャ、それ以外はコピーキャプチャ | |
[&, hoge] | オブジェクト hoge をコピーキャプチャ、それ以外は参照キャプチャ | |
[this] | メンバ関数内でλ式を記述する歳、thisポインタをコピーキャプチャする | |
[+this] | メンバ関数内でλ式を記述する歳、*thisオブジェクトをコピーキャプチャする | C++17 |
- 戻り値型には auto を指定することが出来る
- noreturn
- 呼び出しても戻ってこない関数の記述に使用する
[[ noreturn ]] void f();
- noreturn 属性を指定された関数が throw を送出すれば、その関数から「戻る」ことが可能。
- noreturn 属性を指定された関数が return 文を実行したり、関数末尾に到達して呼び出し元に戻った場合の挙動は未定義。
- carries_dependency
- 関数間でデータの依存性を伝播するために使用する
- 詳細は要確認
例外クラスの使い分け†
例外を送出しないことを明示する†
例外ポインタ†
入れ子の例外関連†
std::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 --- 数値を文字列に変換する†
#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 );
正規表現での検索†
浮動小数点数の入力†
日付・時刻†
乱数生成†
shared_ptr (共有ポインタ)†
- std::shared_ptr
- #include <memory>
- 通常のポインタ同様の操作が出来る
- 複数の std::shared_ptr が1つのリソースを指し示すことが出来る
- 同じリソースを参照する std::shared_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 );
}
リソース開放時の処理の指定†
- リソースを開放するときの処理を指定することが出来る。
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() --- 組み込みポインタの取得†
std::shared_ptr<ClassA> up_a1;
ClassA *p_a1 = up_a1.get(); // up_a1 が持っている ClassA のリソースを指す組み込みポインタを取得
std::make_shared() --- std::shared_ptr 構築のためのヘルパ関数†
- この関数は内部で 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 );
}
decltype†
- 与えられた式から型を取得する
- 例1
int foo();
decltype(foo()) i; // i は int 型に決定される。
- 例2
template <typename T1, typename T2>
auto func(T1 x T2 y) -> decltype(x + y) {
return (x + y);
}
// このとき、
// T1, T2 が共に int → 戻り値は int
// T1 が int, T2 がdouble → 戻り値は double
auto 型†
auto 型の利点†
- タイプ量を節約出来る
- 初期化子から型推論される為、初期化が必須となっている。即ち、未初期化となることがない。
- 型推論する為、コンパイラにしか分からない型でも表現可能。
- C++14 では、λ式の仮引数にも使用可能になっている。
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 は複数箇所から参照できない。これを書くとエラーになる
// 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 の移動†
std::unique_ptr::get() --- 組み込みポインタの取得†
std::unique_ptr<ClassX> up_x1;
ClassX *p_x1 = up_x1.get(); // up_x1 が持っている ClassX のリソースを指す組み込みポインタを取得
複数の値から、最大値または最小値を選択する†
2つの変数を入れ替える†
コンパイル時にアサーションを行う†
浮動小数点数の四捨五入†
数学関数†
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;
時間演算を行う†
タプル†
- #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 );
}
constexpr†
static_assert†
システム終了†
スレッド†
コンテナ†
build (clang++/g++)†
- コンパイラオプションに "-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 );
~~~~~^