SlideShare a Scribd company logo
1 of 11
Download to read offline
C++
テンプレートメタプログラミング

                           高橋晶(アキラ)

   ブログ:「Faith and Brave – C++で遊ぼう」
    http://d.hatena.ne.jp/faith_and_brave/
はじめに
Q.テンプレートメタプログラミングってなんぞ?

A.テンプレートのインスタンス化を利用して
  コンパイル時に評価されるプログラムを書こうぜ!
  っていうパラダイム
メタ関数
• コンパイル時に評価される関数
 template <class T> // Tがパラメータ
 struct identity {
    typedef T type; // typeが戻り値
 };

 identity<int>::type i; // int i;


テンプレートパラメータを関数のパラメータ、
入れ子型(nested-type)や
クラス内定数(static const T)を関数の戻り値を見なす。
特殊化で型特性の判別と条件分岐
テンプレートの特殊化を使って、
型がどんな特性を持ってるのかを判別する

以下はTがvoidかどうかを判別するメタ関数
 template <class T>
 struct is_void {        // void以外だったらfalseを返す
    static const bool value = false;
 };
 template <>
 struct is_void<void> { // voidだったらtrueを返す
    static const bool value = true;
 };
 bool a = is_void<int>::value; // bool a = false;
 bool b = is_void<void>::value; // bool b = true;
部分特殊化で型特性の判別
• 部分特殊化使った場合。
  パターンマッチみたいなもん。
 template <class T>
 struct is_pointer {      // ポインタ以外はfalseを返す
    static const bool value = false;
 };

 template <class T>
 struct is_pointer<T*> { // ポインタならtrueを返す
    static const bool value = true;
 };

 bool a = is_pointer<int>::value; // bool a = false;
 bool b = is_pointer<int*>::value; // bool b = true;
型を修飾する
• Tを受け取ってT*を返すメタ関数
 template <class T>
 struct add_pointer {
    typedef T* type;
 };

 add_pointer<int>::type p;
    // int* p;

 add_pointer<add_pointer<int>::type>::type pp;
    // int** pp;
再帰テンプレート
• メタ関数がメタ関数自身を呼ぶことによって
  再帰によるループを表現する
template <class T, int N>
struct add_pointer {
   typedef typename add_pointer<T*, N-1>::type type;
};

template <class T>
struct add_pointer<T, 0> { // 再帰の終了条件
   typedef T type;
};

add_pointer<int, 5> p; // int***** p;
応用例1 : コンパイル時if文(型の選択)
 テンプレートパラメータで条件式をbool値で受け取って
 パラメータがtrueの場合の型、falseの場合の型を選択する

 template <bool Cond, class Then, class Else>
 struct if_c;

 template <class Then, class Else>
 struct if_c<true, Then, Else> {
   typedef Then type;
 };

 template <class Then, class Else>
 struct if_c<false, Then, Else> {
   typedef Else type;
 };

 if_c<true, int, char>::type
 → int

 if_c<false, int, char>::type
 → char
応用例2 :
      コンテナ/配列からイテレータ/ポインタの型を取り出す
template <class Range>
struct range_iterator {        // 配列以外だったらRange::iterator型を返す
   typedef typename Range::iterator type;
};

template <class T, int N>
struct range_iterator<T[N]> { // 配列だったらT*型を返す
   typedef T* type;
};

template <class Range>
void foo(Range& r)
{
  typedef typename range_iterator<Range>::type Iterator;
}

vector<int> v;
int ar[3];

foo(v); // Iteratorの型はvector<int>::iteratorになる
foo(ar); // Iteratorの型はint*になる
応用例3:
        型のシグニチャから部分的に型を抜き出す
template <class Signature>
struct argument_of;

template <class R, class Arg>
struct argument_of<R(Arg)> { // 型がR(Arg)の形になってたら
   typedef R   result_type;   // 戻り値の型を取り出す
   typedef Arg argument_type; // 引数の型を取り出す
};

typedef argument_of<int(double)>::result_type   result;   // int
typedef argument_of<int(double)>::argument_type argument; // double



boost::result_ofで関数オブジェクトの戻り値の型を取得するときに使える
チューリング完全
特殊化によって条件分岐を表現し、
再帰テンプレートによってループを表現できる

これらのことから、C++テンプレートは
ほぼ(※)チューリング完全だと言われてるみたい。
つまり、コンパイル時に全てのアルゴリズムを解くことができる。

※再帰的に入れ子にされたテンプレートの
 インスタンス化は17回までは保証されてる。

『C++ Templates are Turing Complete』
http://ubiety.uwaterloo.ca/~tveldhui/papers/2003/turing.pdf

More Related Content

What's hot

Constexpr 中3女子テクニック
Constexpr 中3女子テクニックConstexpr 中3女子テクニック
Constexpr 中3女子テクニック
Genya Murakami
 
組み込みでこそC++を使う10の理由
組み込みでこそC++を使う10の理由組み込みでこそC++を使う10の理由
組み込みでこそC++を使う10の理由
kikairoya
 
オブジェクト指向できていますか?
オブジェクト指向できていますか?オブジェクト指向できていますか?
オブジェクト指向できていますか?
Moriharu Ohzu
 

What's hot (20)

関数型プログラミングのデザインパターンひとめぐり
関数型プログラミングのデザインパターンひとめぐり関数型プログラミングのデザインパターンひとめぐり
関数型プログラミングのデザインパターンひとめぐり
 
マーク&スイープ勉強会
マーク&スイープ勉強会マーク&スイープ勉強会
マーク&スイープ勉強会
 
Constexpr 中3女子テクニック
Constexpr 中3女子テクニックConstexpr 中3女子テクニック
Constexpr 中3女子テクニック
 
C++コミュニティーの中心でC++をDISる
C++コミュニティーの中心でC++をDISるC++コミュニティーの中心でC++をDISる
C++コミュニティーの中心でC++をDISる
 
templateとautoの型推論
templateとautoの型推論templateとautoの型推論
templateとautoの型推論
 
C/C++プログラマのための開発ツール
C/C++プログラマのための開発ツールC/C++プログラマのための開発ツール
C/C++プログラマのための開発ツール
 
Kotlinアンチパターン
KotlinアンチパターンKotlinアンチパターン
Kotlinアンチパターン
 
たのしい高階関数
たのしい高階関数たのしい高階関数
たのしい高階関数
 
明日使えないすごいビット演算
明日使えないすごいビット演算明日使えないすごいビット演算
明日使えないすごいビット演算
 
モダン PHP テクニック 12 選 ―PsalmとPHP 8.1で今はこんなこともできる!―
モダン PHP テクニック 12 選 ―PsalmとPHP 8.1で今はこんなこともできる!―モダン PHP テクニック 12 選 ―PsalmとPHP 8.1で今はこんなこともできる!―
モダン PHP テクニック 12 選 ―PsalmとPHP 8.1で今はこんなこともできる!―
 
最新C++事情 C++14-C++20 (2018年10月)
最新C++事情 C++14-C++20 (2018年10月)最新C++事情 C++14-C++20 (2018年10月)
最新C++事情 C++14-C++20 (2018年10月)
 
unique_ptrにポインタ以外のものを持たせるとき
unique_ptrにポインタ以外のものを持たせるときunique_ptrにポインタ以外のものを持たせるとき
unique_ptrにポインタ以外のものを持たせるとき
 
Glibc malloc internal
Glibc malloc internalGlibc malloc internal
Glibc malloc internal
 
組み込みでこそC++を使う10の理由
組み込みでこそC++を使う10の理由組み込みでこそC++を使う10の理由
組み込みでこそC++を使う10の理由
 
オブジェクト指向できていますか?
オブジェクト指向できていますか?オブジェクト指向できていますか?
オブジェクト指向できていますか?
 
C++の話(本当にあった怖い話)
C++の話(本当にあった怖い話)C++の話(本当にあった怖い話)
C++の話(本当にあった怖い話)
 
ゲーム開発者のための C++11/C++14
ゲーム開発者のための C++11/C++14ゲーム開発者のための C++11/C++14
ゲーム開発者のための C++11/C++14
 
Javaバイトコード入門
Javaバイトコード入門Javaバイトコード入門
Javaバイトコード入門
 
Return Oriented Programming
Return Oriented ProgrammingReturn Oriented Programming
Return Oriented Programming
 
C/C++とWebAssemblyを利用したライブラリ開発
C/C++とWebAssemblyを利用したライブラリ開発C/C++とWebAssemblyを利用したライブラリ開発
C/C++とWebAssemblyを利用したライブラリ開発
 

Viewers also liked

すごい constexpr たのしくレイトレ!
すごい constexpr たのしくレイトレ!すごい constexpr たのしくレイトレ!
すごい constexpr たのしくレイトレ!
Genya Murakami
 
constexpr関数はコンパイル時処理。これはいい。実行時が霞んで見える。cpuの嬌声が聞こえてきそうだ
constexpr関数はコンパイル時処理。これはいい。実行時が霞んで見える。cpuの嬌声が聞こえてきそうだconstexpr関数はコンパイル時処理。これはいい。実行時が霞んで見える。cpuの嬌声が聞こえてきそうだ
constexpr関数はコンパイル時処理。これはいい。実行時が霞んで見える。cpuの嬌声が聞こえてきそうだ
Genya Murakami
 
C++0x Variadic Type List
C++0x Variadic Type ListC++0x Variadic Type List
C++0x Variadic Type List
Akira Takahashi
 
闇魔術を触ってみた
闇魔術を触ってみた闇魔術を触ってみた
闇魔術を触ってみた
Satoshi Sato
 

Viewers also liked (18)

エクストリームC++11/14プログラミング
エクストリームC++11/14プログラミングエクストリームC++11/14プログラミング
エクストリームC++11/14プログラミング
 
すごい constexpr たのしくレイトレ!
すごい constexpr たのしくレイトレ!すごい constexpr たのしくレイトレ!
すごい constexpr たのしくレイトレ!
 
constexpr関数はコンパイル時処理。これはいい。実行時が霞んで見える。cpuの嬌声が聞こえてきそうだ
constexpr関数はコンパイル時処理。これはいい。実行時が霞んで見える。cpuの嬌声が聞こえてきそうだconstexpr関数はコンパイル時処理。これはいい。実行時が霞んで見える。cpuの嬌声が聞こえてきそうだ
constexpr関数はコンパイル時処理。これはいい。実行時が霞んで見える。cpuの嬌声が聞こえてきそうだ
 
C++0x Variadic Type List
C++0x Variadic Type ListC++0x Variadic Type List
C++0x Variadic Type List
 
boost and c++11
boost and c++11boost and c++11
boost and c++11
 
中3女子が狂える本当に気持ちのいい constexpr
中3女子が狂える本当に気持ちのいい constexpr中3女子が狂える本当に気持ちのいい constexpr
中3女子が狂える本当に気持ちのいい constexpr
 
中3女子でもわかる constexpr
中3女子でもわかる constexpr中3女子でもわかる constexpr
中3女子でもわかる constexpr
 
C++1z draft
C++1z draftC++1z draft
C++1z draft
 
Lisp Meet Up #25, 8-bit PIC マイコン用ネイティブコンパイラの作成
Lisp Meet Up #25, 8-bit PIC マイコン用ネイティブコンパイラの作成Lisp Meet Up #25, 8-bit PIC マイコン用ネイティブコンパイラの作成
Lisp Meet Up #25, 8-bit PIC マイコン用ネイティブコンパイラの作成
 
What is template
What is templateWhat is template
What is template
 
More C++11
More C++11More C++11
More C++11
 
Boost.SIMD
Boost.SIMDBoost.SIMD
Boost.SIMD
 
C++でCプリプロセッサを作ったり速くしたりしたお話
C++でCプリプロセッサを作ったり速くしたりしたお話C++でCプリプロセッサを作ったり速くしたりしたお話
C++でCプリプロセッサを作ったり速くしたりしたお話
 
闇魔術を触ってみた
闇魔術を触ってみた闇魔術を触ってみた
闇魔術を触ってみた
 
C++14 Overview
C++14 OverviewC++14 Overview
C++14 Overview
 
C++の黒魔術
C++の黒魔術C++の黒魔術
C++の黒魔術
 
プログラムの処方箋~健康なコードと病んだコード
プログラムの処方箋~健康なコードと病んだコードプログラムの処方箋~健康なコードと病んだコード
プログラムの処方箋~健康なコードと病んだコード
 
夜寝ていたら突然本番障害だと起こされて異世界に召還されたときに役に立つこと
夜寝ていたら突然本番障害だと起こされて異世界に召還されたときに役に立つこと夜寝ていたら突然本番障害だと起こされて異世界に召還されたときに役に立つこと
夜寝ていたら突然本番障害だと起こされて異世界に召還されたときに役に立つこと
 

Similar to C++ Template Metaprogramming

Lambda in template_final
Lambda in template_finalLambda in template_final
Lambda in template_final
Cryolite
 
Replace Output Iterator and Extend Range JP
Replace Output Iterator and Extend Range JPReplace Output Iterator and Extend Range JP
Replace Output Iterator and Extend Range JP
Akira Takahashi
 

Similar to C++ Template Metaprogramming (15)

C++0x concept
C++0x conceptC++0x concept
C++0x concept
 
Effective Modern C++ 勉強会#1 Item3,4
Effective Modern C++ 勉強会#1 Item3,4Effective Modern C++ 勉強会#1 Item3,4
Effective Modern C++ 勉強会#1 Item3,4
 
C++0x 言語の未来を語る
C++0x 言語の未来を語るC++0x 言語の未来を語る
C++0x 言語の未来を語る
 
Lambda in template_final
Lambda in template_finalLambda in template_final
Lambda in template_final
 
ナウなヤングにバカうけのイカしたタグ付き共用体
ナウなヤングにバカうけのイカしたタグ付き共用体ナウなヤングにバカうけのイカしたタグ付き共用体
ナウなヤングにバカうけのイカしたタグ付き共用体
 
Pythonと型チェッカー
Pythonと型チェッカーPythonと型チェッカー
Pythonと型チェッカー
 
Replace Output Iterator and Extend Range JP
Replace Output Iterator and Extend Range JPReplace Output Iterator and Extend Range JP
Replace Output Iterator and Extend Range JP
 
Python と型ヒント (Type Hints)
Python と型ヒント (Type Hints)Python と型ヒント (Type Hints)
Python と型ヒント (Type Hints)
 
わんくま同盟大阪勉強会#61
わんくま同盟大阪勉強会#61わんくま同盟大阪勉強会#61
わんくま同盟大阪勉強会#61
 
boost tour 1.48.0 all
boost tour 1.48.0 allboost tour 1.48.0 all
boost tour 1.48.0 all
 
constexpr idioms
constexpr idiomsconstexpr idioms
constexpr idioms
 
Boost tour 1_40_0
Boost tour 1_40_0Boost tour 1_40_0
Boost tour 1_40_0
 
Emcpp item31
Emcpp item31Emcpp item31
Emcpp item31
 
Emcjp item21
Emcjp item21Emcjp item21
Emcjp item21
 
拡張可能でprintfっぽい書式指定ができて書式指定文字列と引数をコンパイル時に検証できる文字列フォーマット関数を作った
拡張可能でprintfっぽい書式指定ができて書式指定文字列と引数をコンパイル時に検証できる文字列フォーマット関数を作った拡張可能でprintfっぽい書式指定ができて書式指定文字列と引数をコンパイル時に検証できる文字列フォーマット関数を作った
拡張可能でprintfっぽい書式指定ができて書式指定文字列と引数をコンパイル時に検証できる文字列フォーマット関数を作った
 

More from Akira Takahashi

C++14 solve explicit_default_constructor
C++14 solve explicit_default_constructorC++14 solve explicit_default_constructor
C++14 solve explicit_default_constructor
Akira Takahashi
 
Executors and schedulers
Executors and schedulersExecutors and schedulers
Executors and schedulers
Akira Takahashi
 

More from Akira Takahashi (20)

Cpp20 overview language features
Cpp20 overview language featuresCpp20 overview language features
Cpp20 overview language features
 
Cppmix 02
Cppmix 02Cppmix 02
Cppmix 02
 
Cppmix 01
Cppmix 01Cppmix 01
Cppmix 01
 
Modern C++ Learning
Modern C++ LearningModern C++ Learning
Modern C++ Learning
 
cpprefjp documentation
cpprefjp documentationcpprefjp documentation
cpprefjp documentation
 
Boost tour 1_61_0 merge
Boost tour 1_61_0 mergeBoost tour 1_61_0 merge
Boost tour 1_61_0 merge
 
Boost tour 1_61_0
Boost tour 1_61_0Boost tour 1_61_0
Boost tour 1_61_0
 
error handling using expected
error handling using expectederror handling using expected
error handling using expected
 
Boost tour 1.60.0 merge
Boost tour 1.60.0 mergeBoost tour 1.60.0 merge
Boost tour 1.60.0 merge
 
Boost tour 1.60.0
Boost tour 1.60.0Boost tour 1.60.0
Boost tour 1.60.0
 
Boost container feature
Boost container featureBoost container feature
Boost container feature
 
Boost Tour 1_58_0 merge
Boost Tour 1_58_0 mergeBoost Tour 1_58_0 merge
Boost Tour 1_58_0 merge
 
Boost Tour 1_58_0
Boost Tour 1_58_0Boost Tour 1_58_0
Boost Tour 1_58_0
 
C++14 solve explicit_default_constructor
C++14 solve explicit_default_constructorC++14 solve explicit_default_constructor
C++14 solve explicit_default_constructor
 
C++14 enum hash
C++14 enum hashC++14 enum hash
C++14 enum hash
 
Multi paradigm design
Multi paradigm designMulti paradigm design
Multi paradigm design
 
Start Concurrent
Start ConcurrentStart Concurrent
Start Concurrent
 
Programmer mind
Programmer mindProgrammer mind
Programmer mind
 
Boost.Study 14 Opening
Boost.Study 14 OpeningBoost.Study 14 Opening
Boost.Study 14 Opening
 
Executors and schedulers
Executors and schedulersExecutors and schedulers
Executors and schedulers
 

C++ Template Metaprogramming