C++

擬似仮想関数テンプレート

たまに仮想関数をテンプレート関数にしたくなることがあるが、C++ではできない。 #include <iostream> #include <typeinfo> namespace lib { class IDynamicType { public: virtual ~IDynamicType() = default; template<typename StaticType> virtual void function(const StaticType &value) = 0; //</typename></typeinfo></iostream>…

C++11:定数式の一般化とその保障:constexpr

C++11では、定数式を定義できるようになった。 enum class Flag: unsigned int { good = 1, fail = 2, bad = 4, eof = 8 }; constexpr Flag operator|(Flag x, Flag y) { return static_cast<Flag>( static_cast<unsigned int>(x) | static_cast<unsigned int>(y)); } void func(Flag f) { swit</unsigned></unsigned></flag>…

C++11:スコープ付きの強く型付けされた列挙体:enum class

C++11では、enum(従来の列挙体)の3つの問題を解決したenum classが導入された。 暗黙的にint型へ変換できるため、整数として振舞わせたくない場合にエラーの原因となる。 列挙子がスコープの外から見えるため、名前の衝突を引き起こす。 根底型(内部表現…

C++11:デフォルト関数の生成の制御:defaultおよびdelete

C++11では、「コピーを禁止する」という慣用句(イディオム)を直接表現できるようになった。 class Foo { Foo(const Foo &) = delete; Foo &operator=(const Foo &) = delete; // ... }; C++98では、private宣言して定義しないという手法がよく用いられた。…

C++11:入れ子になったテンプレート引数

C++11では、入れ子になったテンプレート引数の閉じ括弧が連続する場合に空白が不要になった。 std::map<int, std::vector<std::string>> m; C++98では、右シフト演算子や入力演算子と区別するために、空白が必要だった。 std::map<int, std::vector<std::string> > m; 参考 right-angle brackets(不等号閉じ括弧) プログ</int,></int,>…

C++11:範囲for文

C++11では、ある範囲内の全要素の処理を簡潔に書けるようになった。 for ( auto x : 範囲 ) { // ... } 「範囲」は、std::vectorのように反復子を返すメンバー関数begin()/end()が定義されているクラスのオブジェクトでも良いし、組み込み配列のように非メン…

C++11:初期化子からの型の導出:auto

C++11では、「式」から値の型を導出することができるようになった。 auto x = 式; 初期化子から変数の型を導出できるauto型指定子は、型を書くことが面倒な場合や、正確に知ることが難しい場合に便利だろう。 template<class T> void print_all(const std::vector<T> &v)</t></class>…

DLLでLoki::SingletonHolderを使う場合の注意点

C++でSingletonクラスを作成するのに便利なのがLoki::SingletonHolderクラス。しかし、Loki::SingletonHolderはテンプレートクラスかつ静的メンバ変数でオブジェクトを管理しているため、ダイナミックリンクライブラリ(DLL)で使う場合には注意が必要だ。 …