C++TT本

型変換演算子を使って戻り値のオーバーロード風を実現

C++テンプレートテクニック 9-3 戻り値のみでは通常オーバーロードはできません。 #include <iostream> using std::cout; using std::endl; class CClassA {}; class CClassB {}; CClassA foo() { return CClassA(); } CClassB foo() { return CClassB(); } int main (</iostream>…

CRTPを用いて静的な多態性を実現する

C++テンプレートテクニック 8-1 自分自身をテンプレート指定したものを継承するというぱっと聞くと凄く良く分からないお話。見たほうが早い。 #include <iostream> using std::cout; using std::endl; template<class T> class CBase { public: void foo () { static_cast<T&>(*this</t&></class></iostream>…

boost::functionの話

C++テンプレートテクニック 7-3 boost::functionの話が出てきました。言ってしまえば関数ポインタや関数オブジェクトが渡せるオブジェクトなんですが、それを実現するための実装が凄く難しい。とりあえず難易度が高いので関数ポインタだけ受け取るクラスをち…

カスタム削除子

C++テンプレートテクニック 7-3 スマートポインタのメモリ解放処理を関数ポインタ(もしくは関数オブジェクト)を渡すことによって専用の解放処理を実行するという話。以前DirectX用のスマートポインタを作ったことがあるので、今回はそれにカスタム削除子を追…

boost::anyを実装してみる

C++テンプレートテクニック 7-3 boost::anyの話が出てきました。なんでも格納できるクラスです。とりあえず本を参考にしながら出来る範囲内で実装してみます。 #include <iostream> using std::cout; using std::endl; class any { private: // 非テンプレート基本クラ</iostream>…

仮想関数テーブル版Type Erasure

C++テンプレートテクニック 7-2 仮想関数テーブルの話が出てきました。話だけは知っていたのですが、実際のこんな感じという実装を見てイメージが湧きました。しかしdrawひとつ呼ぶのにこれだけコードが必要なのもちょっとどうなのかなぁという感じもします…

Type Erasure

C++テンプレートテクニック 7-1 まずは何でも保存できるvoid*型を利用したテクニックの話。ただしdeleteするときに元の型のデストラクタが呼ばれないのでこのままじゃダメ。

非テンプレート基本クラスとテンプレート派生クラス

C++テンプレートテクニック 7-2 void*を利用したType Erasureではdeleteする際に元クラスのデストラクタが呼ばれないという問題がありました。非テンプレート基本クラスとテンプレート派生クラスを利用すればこの問題が解決します。 #include <iostream> using std::co</iostream>…

enable_ifメタ関数

C++テンプレートテクニック 5-4 Boostにあるenable_ifというメタ関数の話。これはうまい仕組みだなぁ。

型特性メタ関数

C++テンプレートテクニック 5-3 特殊化を利用して型をチェックするメタ関数を作る #include <iostream> using std::cout; using std::endl; template<class T> struct is_pointer { static const bool value = false; }; template<class T> struct is_pointer< T* > { static const bool </class></class></iostream>…

Range-base STL アルゴリズム

C++テンプレートテクニック 5-2 ここの話はいろいろと面白いですね。beginやendを汎用化して呼び分ける。コードも簡素になるし素晴らしいです。ただし、endの定義が以下のように参照の配列を受け取る前提になっているので template<class T,std::size_t N> T* end(T (&ar)[N]) { ret</class>…

継承を利用したポリシー

C++テンプレートテクニック 6-4 http://d.hatena.ne.jp/pknight/20100323/1269358966続き。お次は継承を利用したポリシーです。 #include <iostream> using std::cout; using std::endl; template<class Policy> class CClass : public Policy { public: void func () { this->foo();</class></iostream>…

インスタンスメンバを利用したポリシー

C++テンプレートテクニック 6-4 前回の記事ではstaticメンバ関数を使用したポリシークラスの実装になっていました。今回はインスタンスメンバを使用した場合のポリシーについてです。 #include <iostream> using std::cout; using std::endl; template<class Policy> class CClass { </class></iostream>…

ポリシー

C++テンプレートテクニック 6-1 またしても新しい単語が登場。ポリシー。要約すると同じ関数を持つ別々のクラスを指定できるようにするテンプレートといった感じでしょうか。 #include <iostream> using std::cout; using std::endl; template<class T> void func () { T::foo()</class></iostream>…

SFINAE

C++テンプレートテクニック 5-1 SFINAEという言葉が出てきました。テンプレートのインスタンス化に失敗した場合に、即エラーにするわけではなく、一旦オーバーロードの候補から外して別のテンプレートをインスタンス化する、という感じですかね。前回の記事…

劣化版iterator_traitsを実装してみる

前々回の記事で型変換について学習したのでVector等も渡せる配列操作関数を作成する - (void*)Pないとで出てきたiterator_traitsを実装してみる。 #include <iostream> #include <vector> using std::cout; using std::endl; template<class T> struct types { typedef typename T::valu</class></vector></iostream>…

高階メタ関数

C++テンプレートテクニック 4-6 ここは自分なりのサンプルが全然思いつかなかった。とりあえずまったく意味のないシンプルなコードだけ書いてみた。 #include <iostream> using std::cout; using std::endl; template<class T> struct bar { static const bool value = T::value</class></iostream>…

メタ関数で型を変換する

C++テンプレートテクニック 4-3 テンプレートメタプログラミング - (void*)Pないとの続きです。今度は型を変換するメタ関数の登場です。 #include <iostream> using std::cout; using std::endl; template<class T> struct types { typedef T type; }; int main () { types<int>::typ</int></class></iostream>…

テンプレートメタプログラミング

C++テンプレートテクニック 4-1、4-2 テンプレートのインスタンス化を利用して、コンパイル時にプログラミングをすることをテンプレートメタプログラミングという。 #include <iostream> using std::cout; using std::endl; template<int N> class CClass { public: static co</int></iostream>…

パラメータ化継承

C++テンプレートテクニック 3-6 単に基底クラス名をテンプレート指定するという話ですが template<class T> class Foo : public T { } 何か色々できそうな気はするのですが、具体的な利用法が思い浮かばないですね。</class>

タグ・ディスパッチ

C++テンプレートテクニック 3-5 簡単に言えばオーバーロードを利用した関数の呼び分け処理といった感じでしょうか。シンプルな例を考えてみました。 #include <iostream> using std::cout; using std::endl; // ディスパッチ用のタグ名 struct tag_a {}; struct tag_b </iostream>…

Vector等も渡せる配列操作関数を作成する

C++テンプレートテクニック 3-3 とりあえず例としてfindを作ってみます。 #include <iostream> using std::cout; using std::endl; template<class T> T* myfind (T* first,T* last, T value) { T* p=first; for (; p != last; ++p) { if ( *p == value ) { break; } } return p</class></iostream>…

テンプレート・テンプレート・パラメータ

C++テンプレートテクニック 2-8 template<class T> class CClass { T<int> m_x; }; $ cl /W4 /EHsc main.cpp Microsoft(R) 32-bit C/C++ Optimizing Compiler Version 15.00.30729.01 for 80x86 Copyright (C) Microsoft Corporation. All rights reserved. main.cpp main.</int></class>…

template限定子

C++テンプレートテクニック 2-6 template<class T> int foo(T x,int n) { return x.get<3>(n); } 上記のようなテンプレートの場合、「x.get(n)」は変数xのgetメンバ関数の呼び出しを期待しているわけなのだが、変数xのgetメンバ変数と3を比較するという処理、つまり「</class>…

typenameキーワード

C++テンプレートテクニック 2-6 テンプレートの曖昧さ回避のために使用するらしい。 #include <iostream> using std::cout; using std::endl; struct ClassA { typedef int result; }; struct ClassB { static const int result = 5; }; int p; template<class T> void func (T)</class></iostream>…

コンストラクタテンプレート

C++テンプレートテクニック 2-5 コンストラクタテンプレートという名前がついてますが、要はクラステンプレートとメンバ関数テンプレートの合わせ技ですね。 関連 http://d.hatena.ne.jp/pknight/20090805/1249471903

テンプレート引数にポインタを渡す

C++テンプレートテクニック 2-4 テンプレート引数にはコンパイル時に値が確定しているグローバル変数や関数のポインタも渡すことができます。 #include <iostream> using std::cout; using std::endl; template<class T,void (T::*M)()> void func (T obj) { (obj.*M)(); } class CClass { publ</class></iostream>…

テンプレートと参照渡しを利用して配列の要素数を取得する

C++テンプレートテクニック 2-4 #include <iostream> using std::cout; using std::endl; template<class T,int N> int size(T (&)[N]) { return N; } int main () { int a[] = {3,4,5,6}; // 配列aの要素数を表示 cout << size(a) << endl; return 0; } $ main 4配列の参照渡しをした</class></iostream>…

明示的なインスタンス化の注意点

C++テンプレートテクニック 2-2 さて、以下のコードはコンパイルできるでしょうか? #include <iostream> using std::cout; using std::endl; template<class T> class CClass { public: T m_val; CClass (T val) { m_val = val; } void Set (T val) { m_val = val; } T Get () </class></iostream>…

マクロによるテンプレートもどき

C++テンプレートテクニック 1-2 お次はマクロを利用してテンプレートっぽいことをやるという話。ということで前回の記事で作ったreverseをマクロテンプレートもどきで再実装してみた。 #include <iostream> #define ARRAY_NUM(a) (sizeof(a)/sizeof(a[0])) using std::</iostream>…