template meta programming入門から応用まで
TRANSCRIPT
![Page 1: Template Meta Programming入門から応用まで](https://reader033.vdocuments.mx/reader033/viewer/2022051015/556a77dfd8b42a7c758b48da/html5/thumbnails/1.jpg)
Template Meta Programming入門から応用まで
@fimbul11
2013/09/28 C++勉強会 @ tkb #2
![Page 2: Template Meta Programming入門から応用まで](https://reader033.vdocuments.mx/reader033/viewer/2022051015/556a77dfd8b42a7c758b48da/html5/thumbnails/2.jpg)
自己紹介
twitter : @fimbul11github : fimbul
University of Tsukuba B3 専攻 : 情報とメディア技術(mast)
プログラミングとかやってます、歴は2年ちょっとぐらいですC++とかやってます、歴は1年半ぐらいですペン回しとか出来ます、歴は7年ぐらいです
![Page 3: Template Meta Programming入門から応用まで](https://reader033.vdocuments.mx/reader033/viewer/2022051015/556a77dfd8b42a7c758b48da/html5/thumbnails/3.jpg)
このような無名の勉強会に遠方からも多くの人に来ていただけました、本当にありがとうございます
はじめに
![Page 4: Template Meta Programming入門から応用まで](https://reader033.vdocuments.mx/reader033/viewer/2022051015/556a77dfd8b42a7c758b48da/html5/thumbnails/4.jpg)
おしながき
1. Templateの基本確認2. Template Meta Programmingとは3. Template Meta Programming入門4. Template Meta Programming応用5. その他付録6. まとめ7. 質疑応答
![Page 5: Template Meta Programming入門から応用まで](https://reader033.vdocuments.mx/reader033/viewer/2022051015/556a77dfd8b42a7c758b48da/html5/thumbnails/5.jpg)
おしながき
1. Templateの基本確認2. Template Meta Programmingとは3. Template Meta Programming入門4. Template Meta Programming応用5. その他付録6. まとめ7. 質疑応答
![Page 6: Template Meta Programming入門から応用まで](https://reader033.vdocuments.mx/reader033/viewer/2022051015/556a77dfd8b42a7c758b48da/html5/thumbnails/6.jpg)
Templateの基本確認今日は・C++未経験者・C++初心者・C++初心者(意味深)
・C++中級者及び上級者・歩くC++規格レベル・人間C++コンパイラなど色々な方が居る可能性があるので
![Page 7: Template Meta Programming入門から応用まで](https://reader033.vdocuments.mx/reader033/viewer/2022051015/556a77dfd8b42a7c758b48da/html5/thumbnails/7.jpg)
Templateの基本確認今日は・C++未経験者・C++初心者・C++初心者(意味深)
・C++中級者及び上級者・歩くC++規格レベル・人間C++コンパイラなど色々な方が居る可能性があるので
![Page 8: Template Meta Programming入門から応用まで](https://reader033.vdocuments.mx/reader033/viewer/2022051015/556a77dfd8b42a7c758b48da/html5/thumbnails/8.jpg)
Templateの基本確認今日は・C++未経験者・C++初心者・C++初心者(意味深)
・C++中級者及び上級者・歩くC++規格レベル・人間C++コンパイラなど色々な方が居る可能性があるので
![Page 9: Template Meta Programming入門から応用まで](https://reader033.vdocuments.mx/reader033/viewer/2022051015/556a77dfd8b42a7c758b48da/html5/thumbnails/9.jpg)
Templateの基本確認今日は・C++未経験者・C++初心者・C++初心者(意味深)
・C++中級者及び上級者・歩くC++規格レベル・人間C++コンパイラなど色々な方が居る可能性があるので
![Page 10: Template Meta Programming入門から応用まで](https://reader033.vdocuments.mx/reader033/viewer/2022051015/556a77dfd8b42a7c758b48da/html5/thumbnails/10.jpg)
Templateの基本確認今日は・C++未経験者・C++初心者・C++初心者(意味深)
・C++中級者及び上級者・歩くC++規格レベル・人間C++コンパイラなど色々な方が居る可能性があるので
![Page 11: Template Meta Programming入門から応用まで](https://reader033.vdocuments.mx/reader033/viewer/2022051015/556a77dfd8b42a7c758b48da/html5/thumbnails/11.jpg)
Templateの基本確認今日は・C++未経験者・C++初心者・C++初心者(意味深)
・C++中級者及び上級者・歩くC++規格レベル・人間C++コンパイラなど色々な方が居る可能性があるので
![Page 12: Template Meta Programming入門から応用まで](https://reader033.vdocuments.mx/reader033/viewer/2022051015/556a77dfd8b42a7c758b48da/html5/thumbnails/12.jpg)
Templateの基本確認今日は・C++未経験者・C++初心者・C++初心者(意味深)
・C++中級者及び上級者・歩くC++規格レベル・人間C++コンパイラなど色々な方が居る可能性があるので
![Page 13: Template Meta Programming入門から応用まで](https://reader033.vdocuments.mx/reader033/viewer/2022051015/556a77dfd8b42a7c758b48da/html5/thumbnails/13.jpg)
Templateの基本確認
ガチ勢の方はお手柔らかにお願いします
![Page 14: Template Meta Programming入門から応用まで](https://reader033.vdocuments.mx/reader033/viewer/2022051015/556a77dfd8b42a7c758b48da/html5/thumbnails/14.jpg)
Templateの基本確認
初心者は知らないことがあるかもそうでない人も少しおさらいをしておく
という意味で
![Page 15: Template Meta Programming入門から応用まで](https://reader033.vdocuments.mx/reader033/viewer/2022051015/556a77dfd8b42a7c758b48da/html5/thumbnails/15.jpg)
Templateの基本確認
規格に基づいて文法などのTemplateの基本を確認する
![Page 16: Template Meta Programming入門から応用まで](https://reader033.vdocuments.mx/reader033/viewer/2022051015/556a77dfd8b42a7c758b48da/html5/thumbnails/16.jpg)
Templateの基本確認
規格に基づいて文法などのTemplateの基本を確認する
むしろややこしいTemplateのルールについて把握する事こそがTemplate Meta Programming
最大の山場といえます
![Page 17: Template Meta Programming入門から応用まで](https://reader033.vdocuments.mx/reader033/viewer/2022051015/556a77dfd8b42a7c758b48da/html5/thumbnails/17.jpg)
Templateの基本確認
規格に基づいて文法などのTemplateの基本を確認する
非常に重要な部分であり、templateを使った経験が少ないとこれだけで十分すぎるぐらいつらいと思います
![Page 18: Template Meta Programming入門から応用まで](https://reader033.vdocuments.mx/reader033/viewer/2022051015/556a77dfd8b42a7c758b48da/html5/thumbnails/18.jpg)
Templateの基本確認
・C++11規格に沿う・ただし細かい部分には触れない (各自で規格を確認してほしい 自分もまる覚えはしていない)
・C++14~の機能(Variable Templates等)
はその他付録の章で扱う
![Page 19: Template Meta Programming入門から応用まで](https://reader033.vdocuments.mx/reader033/viewer/2022051015/556a77dfd8b42a7c758b48da/html5/thumbnails/19.jpg)
Templateの基本確認
結構量があるので既に知ってる人は適当に聞き流しつつ他の作業でもしていて下さい
![Page 20: Template Meta Programming入門から応用まで](https://reader033.vdocuments.mx/reader033/viewer/2022051015/556a77dfd8b42a7c758b48da/html5/thumbnails/20.jpg)
Templateの基本確認目次1. Template is 何2. テンプレートの文法
2-1. テンプレートパラメータ 2-2. クラステンプレート 2-3. 関数テンプレート 2-4. エイリアステンプレート 2-5. 可変長引数テンプレート 2-6. template template parameter
![Page 21: Template Meta Programming入門から応用まで](https://reader033.vdocuments.mx/reader033/viewer/2022051015/556a77dfd8b42a7c758b48da/html5/thumbnails/21.jpg)
Templateの基本確認目次1. Template is 何2. テンプレートの文法
2-1. テンプレートパラメータ 2-2. クラステンプレート 2-3. 関数テンプレート 2-4. エイリアステンプレート 2-5. 可変長引数テンプレート 2-6. template template parameter
![Page 22: Template Meta Programming入門から応用まで](https://reader033.vdocuments.mx/reader033/viewer/2022051015/556a77dfd8b42a7c758b48da/html5/thumbnails/22.jpg)
Template is 何
テンプレートって何ですか?
![Page 23: Template Meta Programming入門から応用まで](https://reader033.vdocuments.mx/reader033/viewer/2022051015/556a77dfd8b42a7c758b48da/html5/thumbnails/23.jpg)
Template is 何
テンプレートって何ですか?N3337見ましょう
![Page 24: Template Meta Programming入門から応用まで](https://reader033.vdocuments.mx/reader033/viewer/2022051015/556a77dfd8b42a7c758b48da/html5/thumbnails/24.jpg)
Template is 何
14 Templates
A template defines a family of classes or functions or an alias for a family of types.
![Page 25: Template Meta Programming入門から応用まで](https://reader033.vdocuments.mx/reader033/viewer/2022051015/556a77dfd8b42a7c758b48da/html5/thumbnails/25.jpg)
Template is 何
テンプレートは
クラスや関数、型エイリアスのファミリーを定義する
![Page 26: Template Meta Programming入門から応用まで](https://reader033.vdocuments.mx/reader033/viewer/2022051015/556a77dfd8b42a7c758b48da/html5/thumbnails/26.jpg)
Template is 何
確認するまでもなかったかもしれません
次に文法を確認していくことにします
![Page 27: Template Meta Programming入門から応用まで](https://reader033.vdocuments.mx/reader033/viewer/2022051015/556a77dfd8b42a7c758b48da/html5/thumbnails/27.jpg)
Templateの基本確認目次1. Template is 何2. テンプレートの文法
2-1. テンプレートパラメータ 2-2. クラステンプレート 2-3. 関数テンプレート 2-4. エイリアステンプレート 2-5. 可変長引数テンプレート 2-6. template template parameter
![Page 28: Template Meta Programming入門から応用まで](https://reader033.vdocuments.mx/reader033/viewer/2022051015/556a77dfd8b42a7c758b48da/html5/thumbnails/28.jpg)
テンプレートの文法
テンプレートの文法を確認する
![Page 29: Template Meta Programming入門から応用まで](https://reader033.vdocuments.mx/reader033/viewer/2022051015/556a77dfd8b42a7c758b48da/html5/thumbnails/29.jpg)
テンプレートの文法
テンプレートの文法を確認する規格を参照して定義から見ていく
![Page 30: Template Meta Programming入門から応用まで](https://reader033.vdocuments.mx/reader033/viewer/2022051015/556a77dfd8b42a7c758b48da/html5/thumbnails/30.jpg)
テンプレートの文法
テンプレートの文法を確認する
template-declaration:template < template-parameter-list > declaration
template-parameter-list: template-parametertemplate-parameter-list , template-parameter
![Page 31: Template Meta Programming入門から応用まで](https://reader033.vdocuments.mx/reader033/viewer/2022051015/556a77dfd8b42a7c758b48da/html5/thumbnails/31.jpg)
テンプレートの文法
テンプレートの文法を確認する
template-declaration:template < template-parameter-list > declaration
template-parameter-list: template-parametertemplate-parameter-list , template-parameter
![Page 32: Template Meta Programming入門から応用まで](https://reader033.vdocuments.mx/reader033/viewer/2022051015/556a77dfd8b42a7c758b48da/html5/thumbnails/32.jpg)
テンプレートの文法
テンプレートは
template < template-parameter-list > declaration として定義される
![Page 33: Template Meta Programming入門から応用まで](https://reader033.vdocuments.mx/reader033/viewer/2022051015/556a77dfd8b42a7c758b48da/html5/thumbnails/33.jpg)
テンプレートの文法
テンプレートは
template < template-parameter-list > declaration として定義される
![Page 34: Template Meta Programming入門から応用まで](https://reader033.vdocuments.mx/reader033/viewer/2022051015/556a77dfd8b42a7c758b48da/html5/thumbnails/34.jpg)
テンプレートの文法
template-parameter-listは
template-parameter 又はtemplate-parameter-list , template-parameter
として定義される
![Page 35: Template Meta Programming入門から応用まで](https://reader033.vdocuments.mx/reader033/viewer/2022051015/556a77dfd8b42a7c758b48da/html5/thumbnails/35.jpg)
テンプレートの文法
template-parameter-listは
template-parameter 又はtemplate-parameter-list , template-parameter
として定義される
![Page 36: Template Meta Programming入門から応用まで](https://reader033.vdocuments.mx/reader033/viewer/2022051015/556a77dfd8b42a7c758b48da/html5/thumbnails/36.jpg)
Templateの基本確認目次1. Template is 何2. テンプレートの文法
2-1. テンプレートパラメータ 2-2. クラステンプレート 2-3. 関数テンプレート 2-4. エイリアステンプレート 2-5. 可変長引数テンプレート 2-6. template template parameter
![Page 37: Template Meta Programming入門から応用まで](https://reader033.vdocuments.mx/reader033/viewer/2022051015/556a77dfd8b42a7c758b48da/html5/thumbnails/37.jpg)
Template parametersThe syntax for template-parameters is:
template-parameter: type-parameterparameter-declaration
type-parameter:class ...opt identifieropt
class identifieropt= type-idtypename ...opt identifieropttypename identifieropt= type-idtemplate < template-parameter-list > class ...opt identifieropt template < template-parameter-list > class identifieropt= id-expression
optの後の要素は省略可能
![Page 38: Template Meta Programming入門から応用まで](https://reader033.vdocuments.mx/reader033/viewer/2022051015/556a77dfd8b42a7c758b48da/html5/thumbnails/38.jpg)
Template parametersThe syntax for template-parameters is:
template-parameter: type-parameterparameter-declaration
type-parameter:class ...opt identifieropt
class identifieropt= type-idtypename ...opt identifieropttypename identifieropt= type-idtemplate < template-parameter-list > class ...opt identifieropt template < template-parameter-list > class identifieropt= id-expression
optの後の要素は省略可能
![Page 39: Template Meta Programming入門から応用まで](https://reader033.vdocuments.mx/reader033/viewer/2022051015/556a77dfd8b42a7c758b48da/html5/thumbnails/39.jpg)
Template parameters
template-parameterは
type-parameter又はparameter-declaration
である
![Page 40: Template Meta Programming入門から応用まで](https://reader033.vdocuments.mx/reader033/viewer/2022051015/556a77dfd8b42a7c758b48da/html5/thumbnails/40.jpg)
Template parameters
template-parameterは
type-parameter又はparameter-declaration
である
![Page 41: Template Meta Programming入門から応用まで](https://reader033.vdocuments.mx/reader033/viewer/2022051015/556a77dfd8b42a7c758b48da/html5/thumbnails/41.jpg)
まずtype-parameterの定義の一部のみ紹介する
type-parameter : class ...opt identifieropt
class identifieropt= type-idtypename ...opt identifieropttypename identifieropt= type-id
optが付いた要素は省略可能一見種類が多い
type-parameter
![Page 42: Template Meta Programming入門から応用まで](https://reader033.vdocuments.mx/reader033/viewer/2022051015/556a77dfd8b42a7c758b48da/html5/thumbnails/42.jpg)
まずtype-parameterの定義の一部のみ紹介する
type-parameter : class ...opt identifieropt
class identifieropt= type-idtypename ...opt identifieropttypename identifieropt= type-id
対応する色のもの同士は実質同じまた = type-idの部分はデフォルト引数の有無
type-parameter
![Page 43: Template Meta Programming入門から応用まで](https://reader033.vdocuments.mx/reader033/viewer/2022051015/556a77dfd8b42a7c758b48da/html5/thumbnails/43.jpg)
定義の数は一見多いが実際は結構単純
順番に定義の意味を見ていく
type-parameter
![Page 44: Template Meta Programming入門から応用まで](https://reader033.vdocuments.mx/reader033/viewer/2022051015/556a77dfd8b42a7c758b48da/html5/thumbnails/44.jpg)
この4つにおいてtype-parameterの頭の部分ではclassキーワードとtypenameキーワードは同じ意味(他の場所では当然意味が違うので注意する、C++には文脈によって同じキーワードに複数の意味を持たせる文化がある)(例えばtemplate template parameterの場合違う)
type-parameter
![Page 45: Template Meta Programming入門から応用まで](https://reader033.vdocuments.mx/reader033/viewer/2022051015/556a77dfd8b42a7c758b48da/html5/thumbnails/45.jpg)
最も単純なtype-parameterを使ったtemplate例
template<class> (又はtemplate<typename>)
type-parameterのclassとtypenameキーワードは今後の説明ではclassで統一する(スライドの都合上、短い方がありがたい)
type-parameter
![Page 46: Template Meta Programming入門から応用まで](https://reader033.vdocuments.mx/reader033/viewer/2022051015/556a77dfd8b42a7c758b48da/html5/thumbnails/46.jpg)
type-parameter : class ...opt identifieropt
identifierはtype-parameterの名前
例template<class Type>
type-parameter
![Page 47: Template Meta Programming入門から応用まで](https://reader033.vdocuments.mx/reader033/viewer/2022051015/556a77dfd8b42a7c758b48da/html5/thumbnails/47.jpg)
type-parameter : class ...opt identifieropt = type-id
type-idがデフォルト引数になる
例template<class Type = int>
何も渡されなければTypeはintになる
type-parameter
![Page 48: Template Meta Programming入門から応用まで](https://reader033.vdocuments.mx/reader033/viewer/2022051015/556a77dfd8b42a7c758b48da/html5/thumbnails/48.jpg)
関数のデフォルト引数同様に
最初のデフォルト引数を持つパラメータ以降の全パラメータにデフォルト引数が必要
例template<class T1 = int, class T2 = int> class A;
type-parameter
![Page 49: Template Meta Programming入門から応用まで](https://reader033.vdocuments.mx/reader033/viewer/2022051015/556a77dfd8b42a7c758b48da/html5/thumbnails/49.jpg)
デフォルト引数の設定は複数に分けて書いても統合される(N3337 305p)
template<class T1, class T2 = int> class A;template<class T1 = int, class T2> class A; は以下に等しい
template<class T1 = int, class T2 = int> class A;
type-parameter
![Page 50: Template Meta Programming入門から応用まで](https://reader033.vdocuments.mx/reader033/viewer/2022051015/556a77dfd8b42a7c758b48da/html5/thumbnails/50.jpg)
当然後ろの要素から順に設定する必要があるtemplate<class T1 = int, class T2> class A;template<class T1, class T2 = int> class A;
この順だと1行目でダメです
error: no default argument for ‘T2’
type-parameter
![Page 51: Template Meta Programming入門から応用まで](https://reader033.vdocuments.mx/reader033/viewer/2022051015/556a77dfd8b42a7c758b48da/html5/thumbnails/51.jpg)
例まとめtemplate<class> 無名template<class = int> デフォルト引数有りtemplate<class Type> 名前有りtemplate<class Type = int> デフォルト引数有りtemplate<class T1, class T2> 複数のパラメータ
type-parameter
![Page 52: Template Meta Programming入門から応用まで](https://reader033.vdocuments.mx/reader033/viewer/2022051015/556a77dfd8b42a7c758b48da/html5/thumbnails/52.jpg)
別の定義は後の章で見るのでひとまずtype-parameterをこれで終わります
type-parameter
![Page 53: Template Meta Programming入門から応用まで](https://reader033.vdocuments.mx/reader033/viewer/2022051015/556a77dfd8b42a7c758b48da/html5/thumbnails/53.jpg)
Template parameters
template-parameterは
type-parameter又はparameter-declaration
である
![Page 54: Template Meta Programming入門から応用まで](https://reader033.vdocuments.mx/reader033/viewer/2022051015/556a77dfd8b42a7c758b48da/html5/thumbnails/54.jpg)
parameter-declaration
parameter-declaration:attribute-specifier-seqopt decl-specifier-seq declarator
attribute-specifier-seqopt decl-specifier-seq declarator = initializer-clause
attribute-specifier-seqopt decl-specifier-seq abstract-declaratoropt
attribute-specifier-seqopt decl-specifier-seq abstract-declaratoropt= initializer-clause
![Page 55: Template Meta Programming入門から応用まで](https://reader033.vdocuments.mx/reader033/viewer/2022051015/556a77dfd8b42a7c758b48da/html5/thumbnails/55.jpg)
parameter-declarationは
non-type template-parameter (非型テンプレートパラメータ)の場合に使う
parameter-declaration
![Page 56: Template Meta Programming入門から応用まで](https://reader033.vdocuments.mx/reader033/viewer/2022051015/556a77dfd8b42a7c758b48da/html5/thumbnails/56.jpg)
例を見た方が早いtemplate<char C>template<int N>
渡される引数がnon-typeなtemplate-parameter
int Nやchar Cがparameter-declarationにあたる
non-type template-parameter
![Page 57: Template Meta Programming入門から応用まで](https://reader033.vdocuments.mx/reader033/viewer/2022051015/556a77dfd8b42a7c758b48da/html5/thumbnails/57.jpg)
もっと具体的な例
template<
class T, // Tはまだ何型か分からない std::size_t N // Nはstd::size_t型のパラメータ> struct array;
std::array<int, 10>の要素数10を受け取っているNがnon-type template-parameter
non-type template-parameter
![Page 58: Template Meta Programming入門から応用まで](https://reader033.vdocuments.mx/reader033/viewer/2022051015/556a77dfd8b42a7c758b48da/html5/thumbnails/58.jpg)
全ての型が
non-type template-parameterに
なれるわけではない
non-type template-parameter
![Page 59: Template Meta Programming入門から応用まで](https://reader033.vdocuments.mx/reader033/viewer/2022051015/556a77dfd8b42a7c758b48da/html5/thumbnails/59.jpg)
non-type template-parameterになれる条件(重要)
1. integral or enumeration type(実質整数型)
2. pointer to object or pointer to function3. lvalue reference to object or lvalue reference to function4. pointer to member 5. std::nullptr_t (実質ポインタ型) (又はこれらにcv修飾子が付いたもの)
のいずれかを満たす型であるとき
non-type template-parameter
![Page 60: Template Meta Programming入門から応用まで](https://reader033.vdocuments.mx/reader033/viewer/2022051015/556a77dfd8b42a7c758b48da/html5/thumbnails/60.jpg)
non-type template-parameterになれる条件は
要するに整数型かポインタ型か左辺値参照
non-type template-parameter
![Page 61: Template Meta Programming入門から応用まで](https://reader033.vdocuments.mx/reader033/viewer/2022051015/556a77dfd8b42a7c758b48da/html5/thumbnails/61.jpg)
例template<std::size_t N>std::size_tは整数型のtypedefなのでwell-formed
class myClass {};template<myClass Arg>先程の条件を満たさないクラス等はill-formed
non-type template-parameter
![Page 62: Template Meta Programming入門から応用まで](https://reader033.vdocuments.mx/reader033/viewer/2022051015/556a77dfd8b42a7c758b48da/html5/thumbnails/62.jpg)
例 N3337 p305
template<double d> class X; // Error浮動小数点型は条件に一致しないtemplate<double* pd> class Y; // OKpointer to objectなのでOK
template<double& rd> class Z; // OKlvalue referenceなのでOK
non-type template-parameter
![Page 63: Template Meta Programming入門から応用まで](https://reader033.vdocuments.mx/reader033/viewer/2022051015/556a77dfd8b42a7c758b48da/html5/thumbnails/63.jpg)
右辺値は値渡しで受け取る必要があるnon-type template-parameterになれないrvalue referenceは論外だし、const lvalue referenceでもダメ(どうせ渡せる型が小さいデータなのでコピーで然程問題ない)
例template<int N> class X;using type = X<0>; // OK
template<const int& N> class Y;using type = Y<0>// error: ‘0’ is not a valid template argument because it is not an lvalue
non-type template-parameter
![Page 64: Template Meta Programming入門から応用まで](https://reader033.vdocuments.mx/reader033/viewer/2022051015/556a77dfd8b42a7c758b48da/html5/thumbnails/64.jpg)
non-type template-parameterに渡せるものにも条件がある
non-type template-parameter
![Page 65: Template Meta Programming入門から応用まで](https://reader033.vdocuments.mx/reader033/viewer/2022051015/556a77dfd8b42a7c758b48da/html5/thumbnails/65.jpg)
non-type template-parameterに渡せるもの
・定数式・関数のアドレス・外部リンケージのあるオブジェクト・静的クラス・メンバのアドレス
non-type template-parameter
![Page 66: Template Meta Programming入門から応用まで](https://reader033.vdocuments.mx/reader033/viewer/2022051015/556a77dfd8b42a7c758b48da/html5/thumbnails/66.jpg)
non-type template-parameterに渡せるもの
定数式(分類に不安があるが…)
・非型テンプレート引数(先程のNなど)
・コンパイル時定数(constexpr)
(後で説明する)
・sizeofやsizeof...など
non-type template-parameter
![Page 67: Template Meta Programming入門から応用まで](https://reader033.vdocuments.mx/reader033/viewer/2022051015/556a77dfd8b42a7c758b48da/html5/thumbnails/67.jpg)
non-type template-parameterに渡せるもの
関数のアドレス・説明不要、f()などのアドレス
non-type template-parameter
![Page 68: Template Meta Programming入門から応用まで](https://reader033.vdocuments.mx/reader033/viewer/2022051015/556a77dfd8b42a7c758b48da/html5/thumbnails/68.jpg)
non-type template-parameterに渡せるもの
外部リンケージのあるオブジェクト・extern修飾されたもの
non-type template-parameter
![Page 69: Template Meta Programming入門から応用まで](https://reader033.vdocuments.mx/reader033/viewer/2022051015/556a77dfd8b42a7c758b48da/html5/thumbnails/69.jpg)
non-type template-parameterに渡せるもの
静的クラス・メンバのアドレス・説明不要、そのままの意味
non-type template-parameter
![Page 70: Template Meta Programming入門から応用まで](https://reader033.vdocuments.mx/reader033/viewer/2022051015/556a77dfd8b42a7c758b48da/html5/thumbnails/70.jpg)
template-parameterに関しては、他にも細かい事が大量に規定されているので適宜規格を調べる必要がある
template-parameter
![Page 71: Template Meta Programming入門から応用まで](https://reader033.vdocuments.mx/reader033/viewer/2022051015/556a77dfd8b42a7c758b48da/html5/thumbnails/71.jpg)
template-parameterまとめ・テンプレートパラメータには型パラメータ と非型パラメータがある・非型パラメータになるものや渡せるものは 限られている
template-parameter
![Page 72: Template Meta Programming入門から応用まで](https://reader033.vdocuments.mx/reader033/viewer/2022051015/556a77dfd8b42a7c758b48da/html5/thumbnails/72.jpg)
Templateの基本確認目次1. Template is 何2. テンプレートの文法
2-1. テンプレートパラメータ 2-2. クラステンプレート 2-3. 関数テンプレート 2-4. エイリアステンプレート 2-5. 可変長引数テンプレート 2-6. template template parameter
![Page 73: Template Meta Programming入門から応用まで](https://reader033.vdocuments.mx/reader033/viewer/2022051015/556a77dfd8b42a7c758b48da/html5/thumbnails/73.jpg)
Class templates
A class template defines the layout and operations for an unbounded set of related types.
![Page 74: Template Meta Programming入門から応用まで](https://reader033.vdocuments.mx/reader033/viewer/2022051015/556a77dfd8b42a7c758b48da/html5/thumbnails/74.jpg)
Class templates
クラステンプレートは、関連する型(要するに扱う要素の型が違うだけのクラス群)のレイアウトをまとめて定義する
![Page 75: Template Meta Programming入門から応用まで](https://reader033.vdocuments.mx/reader033/viewer/2022051015/556a77dfd8b42a7c758b48da/html5/thumbnails/75.jpg)
Class templates例 汎用的な配列クラス N3337 P315template<class T> class Array {
T* v; // Tは引数として渡された型に置き換わるint sz; public: explicit Array(int); T& operator[](int); T& elem(int i) { return v[i]; }
};
Array<int>やArray<char>は渡した型を扱える
![Page 76: Template Meta Programming入門から応用まで](https://reader033.vdocuments.mx/reader033/viewer/2022051015/556a77dfd8b42a7c758b48da/html5/thumbnails/76.jpg)
Class templatesクラスメンバテンプレート
class Test {public:
template<class T>T f(T arg) { return arg; } // 関数テンプレートは後で取り上げる
};
クラスメンバもテンプレートに出来るoperator等もテンプレート化可能
![Page 77: Template Meta Programming入門から応用まで](https://reader033.vdocuments.mx/reader033/viewer/2022051015/556a77dfd8b42a7c758b48da/html5/thumbnails/77.jpg)
Class templates非型テンプレートパラメータを使う例template<std::size_t N>struct integer { // structも当然テンプレート化可能
static constexpr std::size_t value = N;}; Nの型にconst等は付いていなくても非型テンプレートパラメータは(暗黙に)コンパイル時に値が決まる定数として扱える(constexpr修飾された値の初期化にも使える)
![Page 78: Template Meta Programming入門から応用まで](https://reader033.vdocuments.mx/reader033/viewer/2022051015/556a77dfd8b42a7c758b48da/html5/thumbnails/78.jpg)
Class templates非型テンプレートパラメータを使う例template<std::size_t N>struct integer {
static constexpr std::size_t value = ++N;}; 当然、非型テンプレートパラメータの型の書き換えはill-formedである(定数なのでうっかり試みても失敗する)
error: increment of read-only location ‘N’
![Page 79: Template Meta Programming入門から応用まで](https://reader033.vdocuments.mx/reader033/viewer/2022051015/556a77dfd8b42a7c758b48da/html5/thumbnails/79.jpg)
Class templates
違法な例を招く行為(当然してはいけない)template<class T, T v>struct data { static constexpr T* get_address() {
return const_cast<T*>(&static_cast<const T&>(v));}
};
このような行為は万死に値する
![Page 80: Template Meta Programming入門から応用まで](https://reader033.vdocuments.mx/reader033/viewer/2022051015/556a77dfd8b42a7c758b48da/html5/thumbnails/80.jpg)
Class templates
補足事項Template specializations テンプレートの特殊化
![Page 81: Template Meta Programming入門から応用まで](https://reader033.vdocuments.mx/reader033/viewer/2022051015/556a77dfd8b42a7c758b48da/html5/thumbnails/81.jpg)
Class templates
Template specializationsテンプレートの特殊化template<class T = int> struct A { static int x;};template<class U> void g(U) { }template<> struct A<double> {}; // specialize for T == doubletemplate<> struct A<> { }; // specialize for T == inttemplate<> void g(char) { } // specialize for U == char
テンプレートクラスやテンプレート関数のtype-parameterにある値が入った状態のものは特殊化されているといえる
![Page 82: Template Meta Programming入門から応用まで](https://reader033.vdocuments.mx/reader033/viewer/2022051015/556a77dfd8b42a7c758b48da/html5/thumbnails/82.jpg)
Class templates
class template partial specializationsクラステンプレートの部分特殊化
![Page 83: Template Meta Programming入門から応用まで](https://reader033.vdocuments.mx/reader033/viewer/2022051015/556a77dfd8b42a7c758b48da/html5/thumbnails/83.jpg)
Class templates
例template<class T1, class T2, int I> class A {}; // unspecialized
template<class T, int I> class A<T, T*, I> {};template<class T1, class T2, int I> class A<T1*, T2, I> {};template<class T> class A<int, T*, 5> {};template<class T1, class T2, int I> class A<T1, T2*, I> {};
![Page 84: Template Meta Programming入門から応用まで](https://reader033.vdocuments.mx/reader033/viewer/2022051015/556a77dfd8b42a7c758b48da/html5/thumbnails/84.jpg)
Class templates
template<class T1, class T2, int I> class A {}; // unspecialized
template<class T, int I> class A<T, T*, I> {};
このように抽象的なテンプレートパラメータの数を減らし部分的に具体的要素に置き換えた特殊化を作る事が出来る
![Page 85: Template Meta Programming入門から応用まで](https://reader033.vdocuments.mx/reader033/viewer/2022051015/556a77dfd8b42a7c758b48da/html5/thumbnails/85.jpg)
Class templates
template<class T1, class T2, int I> class A {}; // unspecialized
template<class T, int I> class A<T, T*, I> {};
部分特殊化されたテンプレートは、条件を満たす場合には特殊化されていないテンプレートより優先的にマッチする
![Page 86: Template Meta Programming入門から応用まで](https://reader033.vdocuments.mx/reader033/viewer/2022051015/556a77dfd8b42a7c758b48da/html5/thumbnails/86.jpg)
Class templates
template<class T1, class T2, int I> class A {}; // unspecialized
template<class T, int I> class A<T, T*, I> {}; // classA<int, int*, 0>などの場合だけこちらの定義が使われる
ある条件を満たす場合のみ実装を切り替える事が出来るこれはTemplate Meta Programmingにおいて非常に重要
![Page 87: Template Meta Programming入門から応用まで](https://reader033.vdocuments.mx/reader033/viewer/2022051015/556a77dfd8b42a7c758b48da/html5/thumbnails/87.jpg)
Class templates
また、部分特殊化によってはtemplate<int N>struct A;
template<>struct A<0>;のようにtemplateの中身が空<>になることもあるが特に文法上問題無い
![Page 88: Template Meta Programming入門から応用まで](https://reader033.vdocuments.mx/reader033/viewer/2022051015/556a77dfd8b42a7c758b48da/html5/thumbnails/88.jpg)
Class templates
勿論、型テンプレートパラメータだけでなく非型テンプレートパラメータも部分特殊化出来る(例は後の章で登場する)
![Page 89: Template Meta Programming入門から応用まで](https://reader033.vdocuments.mx/reader033/viewer/2022051015/556a77dfd8b42a7c758b48da/html5/thumbnails/89.jpg)
Class templates
テンプレートの特殊化及び部分特殊化が出来るケースにも条件がある
![Page 90: Template Meta Programming入門から応用まで](https://reader033.vdocuments.mx/reader033/viewer/2022051015/556a77dfd8b42a7c758b48da/html5/thumbnails/90.jpg)
Class templates
テンプレートの特殊化が出来るケース特殊化できるOK : 名前空間スコープNG : クラススコープ
つまりクラスのメンバは特殊化不可能
![Page 91: Template Meta Programming入門から応用まで](https://reader033.vdocuments.mx/reader033/viewer/2022051015/556a77dfd8b42a7c758b48da/html5/thumbnails/91.jpg)
Class templates
テンプレートの部分特殊化が出来るケース部分特殊化できる:
OK : クラステンプレートNG : 関数テンプレート
部分特殊化は非クラスメンバのクラステンプレート限定の機能といえる
![Page 92: Template Meta Programming入門から応用まで](https://reader033.vdocuments.mx/reader033/viewer/2022051015/556a77dfd8b42a7c758b48da/html5/thumbnails/92.jpg)
Class templates
Class templatesまとめ・クラステンプレートは、 関連する型のレ イアウトをまとめて定義する・名前空間スコープのクラステンプレートの み部分特殊化によって実装を切り替え可
![Page 93: Template Meta Programming入門から応用まで](https://reader033.vdocuments.mx/reader033/viewer/2022051015/556a77dfd8b42a7c758b48da/html5/thumbnails/93.jpg)
Templateの基本確認目次1. Template is 何2. テンプレートの文法
2-1. テンプレートパラメータ 2-2. クラステンプレート 2-3. 関数テンプレート 2-4. エイリアステンプレート 2-5. 可変長引数テンプレート 2-6. template template parameter
![Page 94: Template Meta Programming入門から応用まで](https://reader033.vdocuments.mx/reader033/viewer/2022051015/556a77dfd8b42a7c758b48da/html5/thumbnails/94.jpg)
Function templates
A function template defines an unbounded set of related functions.
![Page 95: Template Meta Programming入門から応用まで](https://reader033.vdocuments.mx/reader033/viewer/2022051015/556a77dfd8b42a7c758b48da/html5/thumbnails/95.jpg)
Function templates
関数テンプレートは、関連する関数(要するに扱う要素の型が違うだけの関数群)をまとめて定義する
![Page 96: Template Meta Programming入門から応用まで](https://reader033.vdocuments.mx/reader033/viewer/2022051015/556a77dfd8b42a7c758b48da/html5/thumbnails/96.jpg)
Function templates
例template<class T>T twice(T arg) {
return arg * 2;}
twice(2); // 4twice(2.5); // 5.0
整数も浮動小数点も扱える
![Page 97: Template Meta Programming入門から応用まで](https://reader033.vdocuments.mx/reader033/viewer/2022051015/556a77dfd8b42a7c758b48da/html5/thumbnails/97.jpg)
Function templates
Template argument deductionテンプレート引数の型推論
![Page 98: Template Meta Programming入門から応用まで](https://reader033.vdocuments.mx/reader033/viewer/2022051015/556a77dfd8b42a7c758b48da/html5/thumbnails/98.jpg)
Function templates
先程の例twice(2); twice(2.5);
twice<int>(2)と書かなくとも適切にint版のtwiceが呼ばれ、twice<double>(2.5)と書かなくとも適切にdouble版のtwiceが呼ばれた
![Page 99: Template Meta Programming入門から応用まで](https://reader033.vdocuments.mx/reader033/viewer/2022051015/556a77dfd8b42a7c758b48da/html5/thumbnails/99.jpg)
Function templates
このような引数からテンプレートパラメータ型を推論する機能が
Template argument deduction
![Page 100: Template Meta Programming入門から応用まで](https://reader033.vdocuments.mx/reader033/viewer/2022051015/556a77dfd8b42a7c758b48da/html5/thumbnails/100.jpg)
Function templates
幾つかの例外を除き、渡した型がそのまま推論される
![Page 101: Template Meta Programming入門から応用まで](https://reader033.vdocuments.mx/reader033/viewer/2022051015/556a77dfd8b42a7c758b48da/html5/thumbnails/101.jpg)
Function templates
例外1
・配列型(T[N])はポインタ(T*)に変換される・関数型(R(Args...))は関数ポインタ (R(*(Args...))に変換される
![Page 102: Template Meta Programming入門から応用まで](https://reader033.vdocuments.mx/reader033/viewer/2022051015/556a77dfd8b42a7c758b48da/html5/thumbnails/102.jpg)
Function templates
例外2
・値渡しの場合のみトップレベルのcv修飾子 が無視される
![Page 103: Template Meta Programming入門から応用まで](https://reader033.vdocuments.mx/reader033/viewer/2022051015/556a77dfd8b42a7c758b48da/html5/thumbnails/103.jpg)
Function templates
例外2
template<class T>T test(T arg) { return arg; }
int a = 0;test(a); // Tはint型
const int b = 0;test(b); // Tはint型
![Page 104: Template Meta Programming入門から応用まで](https://reader033.vdocuments.mx/reader033/viewer/2022051015/556a77dfd8b42a7c758b48da/html5/thumbnails/104.jpg)
Function templates
例外2
このような挙動の理由は、値コピーを取る場合、結局元のオブジェクトの値が変更される可能性が無いためとされる
const int b = 0;test(b); // (testの中ではbのコピーが扱われるのでbの値自体が変えられることはない、じゃあコピーするときはconst無視してもいいんじゃね)…とコンパイラは思う
![Page 105: Template Meta Programming入門から応用まで](https://reader033.vdocuments.mx/reader033/viewer/2022051015/556a77dfd8b42a7c758b48da/html5/thumbnails/105.jpg)
Function templates
例外2
constと同様にvolatileも無視される
![Page 106: Template Meta Programming入門から応用まで](https://reader033.vdocuments.mx/reader033/viewer/2022051015/556a77dfd8b42a7c758b48da/html5/thumbnails/106.jpg)
Function templates
例外2
よって値を変更する可能性のある参照やポインタ渡しの場合はcv修飾子も保持される
template<class T>T test(T& arg) { return arg; }
const int b = 0;test(b); // Tはint& const型
![Page 107: Template Meta Programming入門から応用まで](https://reader033.vdocuments.mx/reader033/viewer/2022051015/556a77dfd8b42a7c758b48da/html5/thumbnails/107.jpg)
Function templates
例外2
ただし明示的に渡せば、渡した通りになる
const int b = 0;test<const int>(b); // Tはconst intになる
![Page 108: Template Meta Programming入門から応用まで](https://reader033.vdocuments.mx/reader033/viewer/2022051015/556a77dfd8b42a7c758b48da/html5/thumbnails/108.jpg)
Function templates
例外2
cv修飾子が無視される可能性があるのはトップレベルの型のみである
例えばvector<const int>などのconst int部分はトップレベルではないので無視されない
![Page 109: Template Meta Programming入門から応用まで](https://reader033.vdocuments.mx/reader033/viewer/2022051015/556a77dfd8b42a7c758b48da/html5/thumbnails/109.jpg)
Function templates
当然非型テンプレートも推論してくれるtemplate<class T, T N>constexpr T get(std::integral_constant<T, N>) {
return N;}std::cout << get(std::integral_constant<int, 0>()) << std::endl; // T = int, N = 0と推論され、0が出力される
![Page 110: Template Meta Programming入門から応用まで](https://reader033.vdocuments.mx/reader033/viewer/2022051015/556a77dfd8b42a7c758b48da/html5/thumbnails/110.jpg)
Function templates
std::integral_constant<T, N>
のようにテンプレートクラスのテンプレートパラメータとしてネストされた内部の型でもTやNとして推論出来る
![Page 111: Template Meta Programming入門から応用まで](https://reader033.vdocuments.mx/reader033/viewer/2022051015/556a77dfd8b42a7c758b48da/html5/thumbnails/111.jpg)
Function templates
Template argument deductionの規格を厳密に読んで全てのルールを把握していくだけで尋常じゃない大変さなので残りは省略します
![Page 112: Template Meta Programming入門から応用まで](https://reader033.vdocuments.mx/reader033/viewer/2022051015/556a77dfd8b42a7c758b48da/html5/thumbnails/112.jpg)
Function templates
Function template overloading関数テンプレートのオーバーロード
![Page 113: Template Meta Programming入門から応用まで](https://reader033.vdocuments.mx/reader033/viewer/2022051015/556a77dfd8b42a7c758b48da/html5/thumbnails/113.jpg)
Function templates
部分特殊化は出来ないが特殊化は出来るこれらはオーバーロードされる
template<class T> void output(T val);
template<> void output(const std::string& val);
![Page 114: Template Meta Programming入門から応用まで](https://reader033.vdocuments.mx/reader033/viewer/2022051015/556a77dfd8b42a7c758b48da/html5/thumbnails/114.jpg)
Function templates
オーバーロードの解決に関しては省略する
N333714.5.6.2 Partial ordering of function templates を参照して欲しい
ambiguousになる例など取り上げられている
![Page 115: Template Meta Programming入門から応用まで](https://reader033.vdocuments.mx/reader033/viewer/2022051015/556a77dfd8b42a7c758b48da/html5/thumbnails/115.jpg)
Function templates
Function templatesまとめ
・関数テンプレートは引数から型を推論し てくれる・特殊化、オーバーロードが可能である
![Page 116: Template Meta Programming入門から応用まで](https://reader033.vdocuments.mx/reader033/viewer/2022051015/556a77dfd8b42a7c758b48da/html5/thumbnails/116.jpg)
Templateの基本確認目次1. Template is 何2. テンプレートの文法
2-1. テンプレートパラメータ 2-2. クラステンプレート 2-3. 関数テンプレート 2-4. エイリアステンプレート 2-5. 可変長引数テンプレート 2-6. template template parameter
![Page 117: Template Meta Programming入門から応用まで](https://reader033.vdocuments.mx/reader033/viewer/2022051015/556a77dfd8b42a7c758b48da/html5/thumbnails/117.jpg)
Alias templates
1. A template-declaration in which the declaration is an alias-declaration declares the identifier to be a alias template. An alias template is a name for a family of types. The name of the alias template is a template-name.
![Page 118: Template Meta Programming入門から応用まで](https://reader033.vdocuments.mx/reader033/viewer/2022051015/556a77dfd8b42a7c758b48da/html5/thumbnails/118.jpg)
Alias templates
2. When a template-id refers to the specialization of an alias template, it is equivalent to the associated type obtained by substitution of its template-arguments for the template-parameters in the type-id of the alias template.
![Page 119: Template Meta Programming入門から応用まで](https://reader033.vdocuments.mx/reader033/viewer/2022051015/556a77dfd8b42a7c758b48da/html5/thumbnails/119.jpg)
Alias templates
もはや訳すのも面倒なので実例を見る
![Page 120: Template Meta Programming入門から応用まで](https://reader033.vdocuments.mx/reader033/viewer/2022051015/556a77dfd8b42a7c758b48da/html5/thumbnails/120.jpg)
Alias templates
template <class T>using add_pointer = typename std::add_pointer< T >::type;
add_pointer<T>はstd::add_pointer< T >::typeと同じ型になる
![Page 121: Template Meta Programming入門から応用まで](https://reader033.vdocuments.mx/reader033/viewer/2022051015/556a77dfd8b42a7c758b48da/html5/thumbnails/121.jpg)
Alias templates
別にtemplateである必要は無い
using type = int;
typeはint型の別名として使える、簡単!
![Page 122: Template Meta Programming入門から応用まで](https://reader033.vdocuments.mx/reader033/viewer/2022051015/556a77dfd8b42a7c758b48da/html5/thumbnails/122.jpg)
Alias templates
typedef int integer;
using integer = int;
は同じ効果typedefの代わりとして使える(ただし使えるのはC++11以降)
![Page 123: Template Meta Programming入門から応用まで](https://reader033.vdocuments.mx/reader033/viewer/2022051015/556a77dfd8b42a7c758b48da/html5/thumbnails/123.jpg)
Alias templates
Template Meta Programmingではtypenameとか::typeを書かなくて済むようにする為に使ったりする
template<class T>using add_p = typename std::add_pointer<T>::type;
add_p<int>; // int*
![Page 124: Template Meta Programming入門から応用まで](https://reader033.vdocuments.mx/reader033/viewer/2022051015/556a77dfd8b42a7c758b48da/html5/thumbnails/124.jpg)
Alias templates余談typedefは指定子である指定子の順番に意味は無い
typedef int Integer1; (こっちが多分メジャー)
int typedef Integer2; (稀に見かける)
// どちらもOK
int Integer3 typedef; // これはダメ
![Page 125: Template Meta Programming入門から応用まで](https://reader033.vdocuments.mx/reader033/viewer/2022051015/556a77dfd8b42a7c758b48da/html5/thumbnails/125.jpg)
Alias templates
typedef int Integer1; のようにどうしてtypedef A B;の形がメジャーなのか?
![Page 126: Template Meta Programming入門から応用まで](https://reader033.vdocuments.mx/reader033/viewer/2022051015/556a77dfd8b42a7c758b48da/html5/thumbnails/126.jpg)
Alias templates
次のような例を考えるint typedef type; はOKだがint* typedef type; はダメ
「*」は、指定子(specifier)ではなく、宣言子(declarator)のため
![Page 127: Template Meta Programming入門から応用まで](https://reader033.vdocuments.mx/reader033/viewer/2022051015/556a77dfd8b42a7c758b48da/html5/thumbnails/127.jpg)
Alias templates
結論多分、typedefを最初に書かない場合には宣言子が出てきた時に面倒臭いから
![Page 128: Template Meta Programming入門から応用まで](https://reader033.vdocuments.mx/reader033/viewer/2022051015/556a77dfd8b42a7c758b48da/html5/thumbnails/128.jpg)
Alias templates
後方互換性を気にしなくていいなら正直typedefよりusingを使うと良いと思います(個人的にはusingの方が好き)
![Page 129: Template Meta Programming入門から応用まで](https://reader033.vdocuments.mx/reader033/viewer/2022051015/556a77dfd8b42a7c758b48da/html5/thumbnails/129.jpg)
Alias templates
余談template structなどの状態のメタ関数では遅延されるタイミングで正格評価される場合がある?(エイリアステンプレートにしたところコンパイル時間が大幅に伸びた経験がある)
![Page 130: Template Meta Programming入門から応用まで](https://reader033.vdocuments.mx/reader033/viewer/2022051015/556a77dfd8b42a7c758b48da/html5/thumbnails/130.jpg)
Alias templates
Alias templatesまとめ・usingを使う事で型の別名として使える・typedefと違いテンプレート化出来る
![Page 131: Template Meta Programming入門から応用まで](https://reader033.vdocuments.mx/reader033/viewer/2022051015/556a77dfd8b42a7c758b48da/html5/thumbnails/131.jpg)
Templateの基本確認目次1. Template is 何2. テンプレートの文法
2-1. テンプレートパラメータ 2-2. クラステンプレート 2-3. 関数テンプレート 2-4. エイリアステンプレート 2-5. 可変長引数テンプレート 2-6. template template parameter
![Page 132: Template Meta Programming入門から応用まで](https://reader033.vdocuments.mx/reader033/viewer/2022051015/556a77dfd8b42a7c758b48da/html5/thumbnails/132.jpg)
Variadic templates
1. A template parameter pack is a template parameter that accepts zero or more template arguments.
![Page 133: Template Meta Programming入門から応用まで](https://reader033.vdocuments.mx/reader033/viewer/2022051015/556a77dfd8b42a7c758b48da/html5/thumbnails/133.jpg)
Variadic templates
2. A function parameter pack is a function parameter that accepts zero or more function arguments.
![Page 134: Template Meta Programming入門から応用まで](https://reader033.vdocuments.mx/reader033/viewer/2022051015/556a77dfd8b42a7c758b48da/html5/thumbnails/134.jpg)
Variadic templates
つまり、
・可変長引数を取るクラス・可変長引数を取る関数
の為の可変長引数テンプレート
![Page 135: Template Meta Programming入門から応用まで](https://reader033.vdocuments.mx/reader033/viewer/2022051015/556a77dfd8b42a7c758b48da/html5/thumbnails/135.jpg)
Variadic templatesThe syntax for template-parameters is:
template-parameter: type-parameterparameter-declaration
type-parameter:class ...opt identifieropt
class identifieropt= type-idtypename ...opt identifieropttypename identifieropt= type-idtemplate < template-parameter-list > class ...opt identifieropt template < template-parameter-list > class identifieropt= id-expression
optの後の要素は省略可能
![Page 136: Template Meta Programming入門から応用まで](https://reader033.vdocuments.mx/reader033/viewer/2022051015/556a77dfd8b42a7c758b48da/html5/thumbnails/136.jpg)
Variadic templates
先程Template parametersで飛ばした...opt を使う
また、「...」を規格上ellipsisと呼ぶ先の定義通りデフォルト引数は取れない
![Page 137: Template Meta Programming入門から応用まで](https://reader033.vdocuments.mx/reader033/viewer/2022051015/556a77dfd8b42a7c758b48da/html5/thumbnails/137.jpg)
Variadic templates
template<class... Types> struct Tuple {};
class...の部分は可変長引数テンプレートその名前はTypes
![Page 138: Template Meta Programming入門から応用まで](https://reader033.vdocuments.mx/reader033/viewer/2022051015/556a77dfd8b42a7c758b48da/html5/thumbnails/138.jpg)
Variadic templates
template<class... Types> struct Tuple {};
可変長引数テンプレートは0個以上の引数を好きなだけ受け取れる
勿論、非型テンプレート引数版も可能template<int... Indices> struct Numbers {};
![Page 139: Template Meta Programming入門から応用まで](https://reader033.vdocuments.mx/reader033/viewer/2022051015/556a77dfd8b42a7c758b48da/html5/thumbnails/139.jpg)
Variadic templates
template<class... Types> struct Tuple {};
例Tuple<int, double, char, void*> このように好きなだけ渡せる
template<int... Indices> struct Numbers {};Numbers<1,2,3,4,5>
![Page 140: Template Meta Programming入門から応用まで](https://reader033.vdocuments.mx/reader033/viewer/2022051015/556a77dfd8b42a7c758b48da/html5/thumbnails/140.jpg)
Variadic templates
このような可変長引数部分の事をtemplate parameter pack と呼ぶ
![Page 141: Template Meta Programming入門から応用まで](https://reader033.vdocuments.mx/reader033/viewer/2022051015/556a77dfd8b42a7c758b48da/html5/thumbnails/141.jpg)
Variadic templates
例template<class... Types>struct List;
template<class Type, Type... Args>struct Data;
TypesやArgsはTemplate Parameter Pack
![Page 142: Template Meta Programming入門から応用まで](https://reader033.vdocuments.mx/reader033/viewer/2022051015/556a77dfd8b42a7c758b48da/html5/thumbnails/142.jpg)
Variadic templates
可変長引数テンプレートは基本的には、template parameterのうち最後でなければならない(一部例外がある)
template<class Type, class... Types> // OKtemplate<class... Types, class Type> // NG
![Page 143: Template Meta Programming入門から応用まで](https://reader033.vdocuments.mx/reader033/viewer/2022051015/556a77dfd8b42a7c758b48da/html5/thumbnails/143.jpg)
Variadic templates例外template<std::size_t... Indices1, std::size_t... Indices2>void f(index_tuple<Indices1...>, index_tuple<Indices2...>);
・関数の引数の型が持つパラメータパック を推論する場合・特に可変長引数を持つ型の引数を複数受 け取る場合には複数のパラメータパック を持つことが出来る
![Page 144: Template Meta Programming入門から応用まで](https://reader033.vdocuments.mx/reader033/viewer/2022051015/556a77dfd8b42a7c758b48da/html5/thumbnails/144.jpg)
Variadic templates
pack expansion 受け取ったパラメータパックを展開する
![Page 145: Template Meta Programming入門から応用まで](https://reader033.vdocuments.mx/reader033/viewer/2022051015/556a77dfd8b42a7c758b48da/html5/thumbnails/145.jpg)
Variadic templates
可変長引数として受け取ったテンプレートパラメータパックを使う為には
それを展開する必要がある
![Page 146: Template Meta Programming入門から応用まで](https://reader033.vdocuments.mx/reader033/viewer/2022051015/556a77dfd8b42a7c758b48da/html5/thumbnails/146.jpg)
Variadic templates
展開はpattern and an ellipsisからなる
![Page 147: Template Meta Programming入門から応用まで](https://reader033.vdocuments.mx/reader033/viewer/2022051015/556a77dfd8b42a7c758b48da/html5/thumbnails/147.jpg)
Variadic templates
template<class ResultType, class... Types>ResultType sum(const Types&... Args);
sum<int>(1,2,3,4,5,6,7,8,9,10);
可変長の関数テンプレートにおいて型推論を行い、その結果をTypesに格納して受け取っている
![Page 148: Template Meta Programming入門から応用まで](https://reader033.vdocuments.mx/reader033/viewer/2022051015/556a77dfd8b42a7c758b48da/html5/thumbnails/148.jpg)
Variadic templates
template<class Type, class... Types>Type sum(const Types&... Args);
におけるconst Types&...がパック展開
class... Typesはsum<int>(1,2,3,4,5,6,7,8,9,10);
なのでTypesはint, int, int, int, int, int, int, int, int, int
に推論される
![Page 149: Template Meta Programming入門から応用まで](https://reader033.vdocuments.mx/reader033/viewer/2022051015/556a77dfd8b42a7c758b48da/html5/thumbnails/149.jpg)
Variadic templates
このときTypes...はint, int, int, int, int, int, int, int, int, int に展開される
![Page 150: Template Meta Programming入門から応用まで](https://reader033.vdocuments.mx/reader033/viewer/2022051015/556a77dfd8b42a7c758b48da/html5/thumbnails/150.jpg)
Variadic templatespatternはパック展開時に処理を施すconst Types&...はTypesの受け取った型1つ1つにconst修飾及び参照&を付加した型になる
よってconst Types&...はconst int&, const int&, const int&, const int&, const int&, const int&, const int&, const int&, const int&, const int& に展開される
![Page 151: Template Meta Programming入門から応用まで](https://reader033.vdocuments.mx/reader033/viewer/2022051015/556a77dfd8b42a7c758b48da/html5/thumbnails/151.jpg)
Variadic templates結果としてtemplate<class ResultType, class... Types>ResultType sum(const Types&... Args);はsum<int>(1,2,3,4,5,6,7,8,9,10);のとき
int sum<int>(const int&, const int&, const int&, const int&, const int&, const int&, const int&, const int&, const int&, const int&);
と等価になっている
![Page 152: Template Meta Programming入門から応用まで](https://reader033.vdocuments.mx/reader033/viewer/2022051015/556a77dfd8b42a7c758b48da/html5/thumbnails/152.jpg)
Variadic templates
同様にして関数の引数もparameter packとして受け取っている
template<class ResultType, class... Types>ResultType sum(const Types&... Args);
![Page 153: Template Meta Programming入門から応用まで](https://reader033.vdocuments.mx/reader033/viewer/2022051015/556a77dfd8b42a7c758b48da/html5/thumbnails/153.jpg)
Variadic templates
sum<int>(1,2,3,4,5,6,7,8,9,10);のとき
Args...は1,2,3,4,5,6,7,8,9,10になる
![Page 154: Template Meta Programming入門から応用まで](https://reader033.vdocuments.mx/reader033/viewer/2022051015/556a77dfd8b42a7c758b48da/html5/thumbnails/154.jpg)
Variadic templates例として受け取った数の総和を計算する関数を挙げるtemplate<class Type, class... Types>Type sum(const Types&... Args) { // parameter pack Type result = 0; for(auto& elem : { static_cast<Type>(Args)... }) // pack expansion { result += elem; } return result;}
int main() { std::cout << sum<int>(1,2,3,4,5,6,7,8,9,10) << std::endl; // 55}
![Page 155: Template Meta Programming入門から応用まで](https://reader033.vdocuments.mx/reader033/viewer/2022051015/556a77dfd8b42a7c758b48da/html5/thumbnails/155.jpg)
Variadic templatesこの例ではinitializer-listに対して
{ static_cast<Type>(Args)... }
を展開することで
{static_cast<Type>(1), static_cast<Type>(2), static_cast<Type>(3),
中略, static_cast<Type>(10)}
を生成している
結果として今回は全要素がint型の{1,2,3,4,5,6,7,8,9,10}になる
![Page 156: Template Meta Programming入門から応用まで](https://reader033.vdocuments.mx/reader033/viewer/2022051015/556a77dfd8b42a7c758b48da/html5/thumbnails/156.jpg)
Variadic templates
sum<int>(1,2.0,3.5,4,5,6,7,8,9,10);
のように型が異なる要素が混入していてもキャストしながら展開する事が出来る
![Page 157: Template Meta Programming入門から応用まで](https://reader033.vdocuments.mx/reader033/viewer/2022051015/556a77dfd8b42a7c758b48da/html5/thumbnails/157.jpg)
Variadic templates
補足template parameter packの要素数を得るにはsizeof...を使う
sizeof...(Types)sizeof...(Args)
sizeof...に対してはパックは展開せずに渡すsizeof...(Types...) // NG
![Page 158: Template Meta Programming入門から応用まで](https://reader033.vdocuments.mx/reader033/viewer/2022051015/556a77dfd8b42a7c758b48da/html5/thumbnails/158.jpg)
Variadic templates
余談ピリオドが6つ連続するコードが存在し得る(多分Sprout等で稀にお目にかかれる)
例template<class... T>void f(T......); // なにこれキモイ
![Page 159: Template Meta Programming入門から応用まで](https://reader033.vdocuments.mx/reader033/viewer/2022051015/556a77dfd8b42a7c758b48da/html5/thumbnails/159.jpg)
Variadic templates
これは前半3つのピリオドがVariadic Templatesの展開、後半3つのピリオドがC言語スタイルの可変長引数の...であり、真ん中のカンマが省略されたもの
template<class... T>void f(T..., ...); // ただのellipsis, ellipsisにすぎない
に等しいのでビビる必要は無い
![Page 160: Template Meta Programming入門から応用まで](https://reader033.vdocuments.mx/reader033/viewer/2022051015/556a77dfd8b42a7c758b48da/html5/thumbnails/160.jpg)
Variadic templates
Variadic templatesまとめ・Variadic TemplatesはTemplate Parameter Packと して受け取る・型パラメータ、非型パラメータを扱える・型パラメータは関数の引数の型として利用出来る・非型パラメータは関数の引数として利用出来る・Template Parameter Packはpattern and ellipsis
によって展開してから使う
![Page 161: Template Meta Programming入門から応用まで](https://reader033.vdocuments.mx/reader033/viewer/2022051015/556a77dfd8b42a7c758b48da/html5/thumbnails/161.jpg)
Templateの基本確認目次1. Template is 何2. テンプレートの文法
2-1. テンプレートパラメータ 2-2. クラステンプレート 2-3. 関数テンプレート 2-4. エイリアステンプレート 2-5. 可変長引数テンプレート 2-6. template template parameter
![Page 162: Template Meta Programming入門から応用まで](https://reader033.vdocuments.mx/reader033/viewer/2022051015/556a77dfd8b42a7c758b48da/html5/thumbnails/162.jpg)
The syntax for template-parameters is:
template-parameter: type-parameterparameter-declaration
type-parameter:class ...opt identifieropt
class identifieropt= type-idtypename ...opt identifieropttypename identifieropt= type-idtemplate < template-parameter-list > class ...opt identifieropt template < template-parameter-list > class identifieropt= id-expression
optの後の要素は省略可能
Template Template Parameters
![Page 163: Template Meta Programming入門から応用まで](https://reader033.vdocuments.mx/reader033/viewer/2022051015/556a77dfd8b42a7c758b48da/html5/thumbnails/163.jpg)
Template Template Parameters
template <class Container>class hoge; ではhoge<std::vector<int>> h; は出来てもhoge<std::vector> h; は出来ない
![Page 164: Template Meta Programming入門から応用まで](https://reader033.vdocuments.mx/reader033/viewer/2022051015/556a77dfd8b42a7c758b48da/html5/thumbnails/164.jpg)
Template Template Parameters
要するにテンプレートクラス自体などを受け取る為のテンプレートパラメータ
![Page 165: Template Meta Programming入門から応用まで](https://reader033.vdocuments.mx/reader033/viewer/2022051015/556a77dfd8b42a7c758b48da/html5/thumbnails/165.jpg)
Template Template Parameters
アキラさんのブログに分かりやすい例があったので引用するtemplate <class T>class vector;
template <template<class> class Container>class hoge { Container<int> c;};
hoge<vector> h; // OK
![Page 166: Template Meta Programming入門から応用まで](https://reader033.vdocuments.mx/reader033/viewer/2022051015/556a77dfd8b42a7c758b48da/html5/thumbnails/166.jpg)
Template Template Parameters
template < template-parameter-list > class ...opt identifieropt template < template-parameter-list > class identifieropt= id-expression
このようにして受け取れるoptにellipsisがあるように可変長引数でも可能
![Page 167: Template Meta Programming入門から応用まで](https://reader033.vdocuments.mx/reader033/viewer/2022051015/556a77dfd8b42a7c758b48da/html5/thumbnails/167.jpg)
Template Template Parameters
Template Template Parametersまとめ・テンプレートクラス等を受け取る場合に 使う為のTemplate Parameter
![Page 168: Template Meta Programming入門から応用まで](https://reader033.vdocuments.mx/reader033/viewer/2022051015/556a77dfd8b42a7c758b48da/html5/thumbnails/168.jpg)
おしながき
1. Templateの基本確認2. Template Meta Programmingとは3. Template Meta Programming入門4. Template Meta Programming応用5. その他付録6. まとめ7. 質疑応答
![Page 169: Template Meta Programming入門から応用まで](https://reader033.vdocuments.mx/reader033/viewer/2022051015/556a77dfd8b42a7c758b48da/html5/thumbnails/169.jpg)
Template Meta Programmingとは
お疲れ様でした、テンプレートの機能をひと通り確認するだけで絶望的な量でした
これでも相当、本当に沢山端折って説明したので規格自体はこの数倍の量があります
![Page 170: Template Meta Programming入門から応用まで](https://reader033.vdocuments.mx/reader033/viewer/2022051015/556a77dfd8b42a7c758b48da/html5/thumbnails/170.jpg)
Template Meta Programmingとは
がっかりしたところで、初心者も最低限の知識が付いたと思うので二章に入ります
![Page 171: Template Meta Programming入門から応用まで](https://reader033.vdocuments.mx/reader033/viewer/2022051015/556a77dfd8b42a7c758b48da/html5/thumbnails/171.jpg)
Template Meta Programmingとは
Template Meta Programmingとは何か
![Page 172: Template Meta Programming入門から応用まで](https://reader033.vdocuments.mx/reader033/viewer/2022051015/556a77dfd8b42a7c758b48da/html5/thumbnails/172.jpg)
Template Meta Programmingとは
テンプレートを利用して、型や値に関する演算・処理をコンパイル時に行う技法
よく省略してTMPと呼ばれる
![Page 173: Template Meta Programming入門から応用まで](https://reader033.vdocuments.mx/reader033/viewer/2022051015/556a77dfd8b42a7c758b48da/html5/thumbnails/173.jpg)
Template Meta Programmingとは
テンプレートはコンパイル時に処理されるのでこの技法ではコンパイル時に計算が出来る
![Page 174: Template Meta Programming入門から応用まで](https://reader033.vdocuments.mx/reader033/viewer/2022051015/556a77dfd8b42a7c758b48da/html5/thumbnails/174.jpg)
Template Meta Programmingとは
この技法を用いた機能が標準ライブラリにもtype_traitsをはじめ多く含まれている
![Page 175: Template Meta Programming入門から応用まで](https://reader033.vdocuments.mx/reader033/viewer/2022051015/556a77dfd8b42a7c758b48da/html5/thumbnails/175.jpg)
Template Meta Programmingとは
大きく分けて
・型を処理するもの・値(として型)を処理するもの
に分けられる
![Page 176: Template Meta Programming入門から応用まで](https://reader033.vdocuments.mx/reader033/viewer/2022051015/556a77dfd8b42a7c758b48da/html5/thumbnails/176.jpg)
Template Meta Programmingとは
型を処理するものはたいてい
template<class T>
のような型パラメータを使って型を操作していく
![Page 177: Template Meta Programming入門から応用まで](https://reader033.vdocuments.mx/reader033/viewer/2022051015/556a77dfd8b42a7c758b48da/html5/thumbnails/177.jpg)
Template Meta Programmingとは
値(として型)を処理するものはたいてい
template<int N>
のような非型パラメータを使って値(として使えるような型)を操作していく
![Page 178: Template Meta Programming入門から応用まで](https://reader033.vdocuments.mx/reader033/viewer/2022051015/556a77dfd8b42a7c758b48da/html5/thumbnails/178.jpg)
Template Meta Programmingとは
次章で実例を見ていくとしましょう
![Page 179: Template Meta Programming入門から応用まで](https://reader033.vdocuments.mx/reader033/viewer/2022051015/556a77dfd8b42a7c758b48da/html5/thumbnails/179.jpg)
おしながき
1. Templateの基本確認2. Template Meta Programmingとは3. Template Meta Programming入門4. Template Meta Programming応用5. その他付録6. まとめ7. 質疑応答
![Page 180: Template Meta Programming入門から応用まで](https://reader033.vdocuments.mx/reader033/viewer/2022051015/556a77dfd8b42a7c758b48da/html5/thumbnails/180.jpg)
Template Meta Programming入門
この章では実例を見ていく初心者向けに最も単純な例から取り上げる
![Page 181: Template Meta Programming入門から応用まで](https://reader033.vdocuments.mx/reader033/viewer/2022051015/556a77dfd8b42a7c758b48da/html5/thumbnails/181.jpg)
Template Meta Programming入門
例1
型を受け取って値を返すもの
![Page 182: Template Meta Programming入門から応用まで](https://reader033.vdocuments.mx/reader033/viewer/2022051015/556a77dfd8b42a7c758b48da/html5/thumbnails/182.jpg)
Template Meta Programming入門
例えばある2つの型を比較して
同じ型であればtrue
異なる型であればfalse
を得たい
![Page 183: Template Meta Programming入門から応用まで](https://reader033.vdocuments.mx/reader033/viewer/2022051015/556a77dfd8b42a7c758b48da/html5/thumbnails/183.jpg)
Template Meta Programming入門
そのような機能を提供する
std::is_same
が標準ライブラリにはある
![Page 184: Template Meta Programming入門から応用まで](https://reader033.vdocuments.mx/reader033/viewer/2022051015/556a77dfd8b42a7c758b48da/html5/thumbnails/184.jpg)
Template Meta Programming入門
これは以下のように使う
std::is_same<int, int>::value // truestd::is_same<int, unsigned int>::value // false
![Page 185: Template Meta Programming入門から応用まで](https://reader033.vdocuments.mx/reader033/viewer/2022051015/556a77dfd8b42a7c758b48da/html5/thumbnails/185.jpg)
Template Meta Programming入門
実装はどうなっているのか
![Page 186: Template Meta Programming入門から応用まで](https://reader033.vdocuments.mx/reader033/viewer/2022051015/556a77dfd8b42a7c758b48da/html5/thumbnails/186.jpg)
Template Meta Programming入門
宣言template<class T, class U>struct is_same; ただ2つの型を受け取る
![Page 187: Template Meta Programming入門から応用まで](https://reader033.vdocuments.mx/reader033/viewer/2022051015/556a77dfd8b42a7c758b48da/html5/thumbnails/187.jpg)
Template Meta Programming入門
問題はどうやって判別して結果を変えるか
![Page 188: Template Meta Programming入門から応用まで](https://reader033.vdocuments.mx/reader033/viewer/2022051015/556a77dfd8b42a7c758b48da/html5/thumbnails/188.jpg)
Template Meta Programming入門
答え : 部分特殊化を使う
![Page 189: Template Meta Programming入門から応用まで](https://reader033.vdocuments.mx/reader033/viewer/2022051015/556a77dfd8b42a7c758b48da/html5/thumbnails/189.jpg)
Template Meta Programming入門
template<class T, class U> // different typesstruct is_same {
static constexpr auto value = false;};
template<class T> // same typestruct is_same<T, T> {
static constexpr auto value = true;};
![Page 190: Template Meta Programming入門から応用まで](https://reader033.vdocuments.mx/reader033/viewer/2022051015/556a77dfd8b42a7c758b48da/html5/thumbnails/190.jpg)
Template Meta Programming入門
template<class T>struct is_same<T, T> {
static constexpr auto value = true;};
両辺に同じ型が渡された場合のみこちらの定義が使われる
![Page 191: Template Meta Programming入門から応用まで](https://reader033.vdocuments.mx/reader033/viewer/2022051015/556a77dfd8b42a7c758b48da/html5/thumbnails/191.jpg)
Template Meta Programming入門
条件分岐 → 部分特殊化を使う
![Page 192: Template Meta Programming入門から応用まで](https://reader033.vdocuments.mx/reader033/viewer/2022051015/556a77dfd8b42a7c758b48da/html5/thumbnails/192.jpg)
Template Meta Programming入門
結果の返し方
静的なメンバ定数を定義するstatic constexpr auto value = true; // ただの静的定数でも良い
そうすれば、is_same<int, int>::valueのようにして得られる
![Page 193: Template Meta Programming入門から応用まで](https://reader033.vdocuments.mx/reader033/viewer/2022051015/556a77dfd8b42a7c758b48da/html5/thumbnails/193.jpg)
Template Meta Programming入門
このような実質関数として働くようなテンプレートクラスはmeta functionと呼ばれる
![Page 194: Template Meta Programming入門から応用まで](https://reader033.vdocuments.mx/reader033/viewer/2022051015/556a77dfd8b42a7c758b48da/html5/thumbnails/194.jpg)
Template Meta Programming入門
例2
値を受け取って型を返すもの
![Page 195: Template Meta Programming入門から応用まで](https://reader033.vdocuments.mx/reader033/viewer/2022051015/556a77dfd8b42a7c758b48da/html5/thumbnails/195.jpg)
Template Meta Programming入門
条件式によって違う型を返すメタ関数
![Page 196: Template Meta Programming入門から応用まで](https://reader033.vdocuments.mx/reader033/viewer/2022051015/556a77dfd8b42a7c758b48da/html5/thumbnails/196.jpg)
Template Meta Programming入門std::conditionalと同じ働きのメタ関数
template<bool B, class T, class F> // truestruct conditional { using type = T; }; template<class T, class F> // falsestruct conditional<false, T, F> { using type = F; };
型を返す場合はメンバ型を定義してやる
typename conditional<true, int, char>::type // int
![Page 197: Template Meta Programming入門から応用まで](https://reader033.vdocuments.mx/reader033/viewer/2022051015/556a77dfd8b42a7c758b48da/html5/thumbnails/197.jpg)
Template Meta Programming入門
例3
非型テンプレートパラメータによる演算
![Page 198: Template Meta Programming入門から応用まで](https://reader033.vdocuments.mx/reader033/viewer/2022051015/556a77dfd8b42a7c758b48da/html5/thumbnails/198.jpg)
Template Meta Programming入門
template<int X, int Y>struct add {
static constexpr auto value = X + Y;};
add<1, 2>::value // 3
非型パラメータを用いてコンパイル時に演算
![Page 199: Template Meta Programming入門から応用まで](https://reader033.vdocuments.mx/reader033/viewer/2022051015/556a77dfd8b42a7c758b48da/html5/thumbnails/199.jpg)
Template Meta Programming入門
発展例階乗の計算
![Page 200: Template Meta Programming入門から応用まで](https://reader033.vdocuments.mx/reader033/viewer/2022051015/556a77dfd8b42a7c758b48da/html5/thumbnails/200.jpg)
Template Meta Programming入門template<int i>struct fact{ static constexpr auto value = i * fact<i - 1>::value;}; template<>struct fact<1> // 1の場合{ static constexpr auto value = 1;};
階乗の計算ではvalueの定義にfact<i - 1>::valueを利用することで再帰を実現する
![Page 201: Template Meta Programming入門から応用まで](https://reader033.vdocuments.mx/reader033/viewer/2022051015/556a77dfd8b42a7c758b48da/html5/thumbnails/201.jpg)
Template Meta Programming入門
template<>struct fact<1> // 1の場合{ static constexpr auto value = 1;};
1の部分特殊化が無いと再帰が止まらなくなる事に注意する
![Page 202: Template Meta Programming入門から応用まで](https://reader033.vdocuments.mx/reader033/viewer/2022051015/556a77dfd8b42a7c758b48da/html5/thumbnails/202.jpg)
Template Meta Programming入門注意template<int i>struct fact{ static constexpr auto value = i > 1? i * fact<i - 1>::value : 1; // 再帰が止まらない};
三項演算子はtrueの場合も両辺の型の等価性を確認するために両辺ともインスタンス化しようとするので、再帰が止まらない(trueでもfact<i - 1>::valueをインスタンス化する)
![Page 203: Template Meta Programming入門から応用まで](https://reader033.vdocuments.mx/reader033/viewer/2022051015/556a77dfd8b42a7c758b48da/html5/thumbnails/203.jpg)
Template Meta Programming入門余談インスタンス化を遅らせて出来る限り型のまま処理することで部分特殊化無しで実装出来る場合もあるtemplate<std::size_t i>struct fact{ static constexpr auto value = i * std::conditional< (i > 1), fact<i - 1>, std::integral_constant<std::size_t, 1> >::type::value;}; これは再帰が止まるconditionalの両辺をメタ関数にして遅延評価させる
![Page 204: Template Meta Programming入門から応用まで](https://reader033.vdocuments.mx/reader033/viewer/2022051015/556a77dfd8b42a7c758b48da/html5/thumbnails/204.jpg)
Template Meta Programming入門まとめ1
メタ関数には単純な例だけでも入力として・値を受け取るもの・型を受け取るもの出力として・値を返すもの・型を返すものがある
![Page 205: Template Meta Programming入門から応用まで](https://reader033.vdocuments.mx/reader033/viewer/2022051015/556a77dfd8b42a7c758b48da/html5/thumbnails/205.jpg)
Template Meta Programming入門まとめ2
条件分岐・クラステンプレートの部分特殊化を使う(後でenable_if等も取り上げる)
結果の返し方・型を返すならばメンバ型を定義する・値を返すならば静的メンバ定数を定義する
名前は慣習として型であればtype、値であればvalueを使う
![Page 206: Template Meta Programming入門から応用まで](https://reader033.vdocuments.mx/reader033/viewer/2022051015/556a77dfd8b42a7c758b48da/html5/thumbnails/206.jpg)
Template Meta Programming入門
補足コンパイル時にエラーチェックさせる
![Page 207: Template Meta Programming入門から応用まで](https://reader033.vdocuments.mx/reader033/viewer/2022051015/556a77dfd8b42a7c758b48da/html5/thumbnails/207.jpg)
Template Meta Programming入門配列の要素数は正の値であるべきだtemplate<class T, std::size_t N, bool = (N > 0)> struct array; // 実装無し template<class T, std::size_t N>struct array<T, N, true> {// 実装}; array<int , 0> a; // 実装が無いのでコンパイルエラーになる
このような不正値に対して意図的にコンパイルエラーに出来るようなコードを書く技法は良く使われる
![Page 208: Template Meta Programming入門から応用まで](https://reader033.vdocuments.mx/reader033/viewer/2022051015/556a77dfd8b42a7c758b48da/html5/thumbnails/208.jpg)
Template Meta Programming入門
template<class T, std::size_t N, bool = (N > 0)>
比較演算子は括弧で囲む必要がある
std::vector<std::vector<int>>のようなネストされたテンプレートが>>演算子に解釈される問題はC++11以降では平気
![Page 209: Template Meta Programming入門から応用まで](https://reader033.vdocuments.mx/reader033/viewer/2022051015/556a77dfd8b42a7c758b48da/html5/thumbnails/209.jpg)
Template Meta Programming入門
補足static_assert
![Page 210: Template Meta Programming入門から応用まで](https://reader033.vdocuments.mx/reader033/viewer/2022051015/556a77dfd8b42a7c758b48da/html5/thumbnails/210.jpg)
Template Meta Programming入門コンパイル時アサートstatic_assert(fact<6>::value == 720, "");
コンパイル時に計算可能な値に対して用いるtrueであれば無出力falseであればコンパイルエラーになる
1番目の引数に条件式2番目の引数にエラー時のメッセージを渡す
当然、実行時計算されるような値を渡すと失敗扱い
![Page 211: Template Meta Programming入門から応用まで](https://reader033.vdocuments.mx/reader033/viewer/2022051015/556a77dfd8b42a7c758b48da/html5/thumbnails/211.jpg)
おしながき
1. Templateの基本確認2. Template Meta Programmingとは3. Template Meta Programming入門4. Template Meta Programming応用5. その他付録6. まとめ7. 質疑応答
![Page 212: Template Meta Programming入門から応用まで](https://reader033.vdocuments.mx/reader033/viewer/2022051015/556a77dfd8b42a7c758b48da/html5/thumbnails/212.jpg)
1. 関連知識をおさえる2. 実践(有用なイディオムと例)
Template Meta Programming応用
![Page 213: Template Meta Programming入門から応用まで](https://reader033.vdocuments.mx/reader033/viewer/2022051015/556a77dfd8b42a7c758b48da/html5/thumbnails/213.jpg)
Template Meta Programming応用
これからTMPの応用に入るその前に関連知識を知っておく
![Page 214: Template Meta Programming入門から応用まで](https://reader033.vdocuments.mx/reader033/viewer/2022051015/556a77dfd8b42a7c758b48da/html5/thumbnails/214.jpg)
Template Meta Programming応用
・constexpr
・decltype
・SFINAE
![Page 215: Template Meta Programming入門から応用まで](https://reader033.vdocuments.mx/reader033/viewer/2022051015/556a77dfd8b42a7c758b48da/html5/thumbnails/215.jpg)
補足constexpr
Template Meta Programming応用
![Page 216: Template Meta Programming入門から応用まで](https://reader033.vdocuments.mx/reader033/viewer/2022051015/556a77dfd8b42a7c758b48da/html5/thumbnails/216.jpg)
C++11のconstexprに関して軽く説明する私は陶芸家ではないので今回は深入りはしない
constexprに関して深く知りたい場合は・中3女子でもわかる!constexpr
・中3女子が教える本当に気持ちのいい constexpr
・constexpr中3女子テクニックなどの有益な情報の載ったスライドがWeb上に公開されているので各自Web上で検索して読むなどすると良い
Template Meta Programming応用
![Page 217: Template Meta Programming入門から応用まで](https://reader033.vdocuments.mx/reader033/viewer/2022051015/556a77dfd8b42a7c758b48da/html5/thumbnails/217.jpg)
TMPにおける値の計算は整数しか扱えないという弱点がある(浮動小数点を無理矢理エミュレートしようとする人は居るが…)
(また、一応ratioのようなものもあるが…)
またコンパイル時にしか使えないint a = 0;add<a, 1>::value; // エラー、aは実行時オブジェクト
Template Meta Programming応用
![Page 218: Template Meta Programming入門から応用まで](https://reader033.vdocuments.mx/reader033/viewer/2022051015/556a77dfd8b42a7c758b48da/html5/thumbnails/218.jpg)
C++03やconstexpr非対応のコンパイラの場合はTMPを使うが、そうでない場合はただ値を計算して、値を返すだけのようなメタ関数はconstexpr関数で実装した方が好ましい事も多いと思われる
Template Meta Programming応用
![Page 219: Template Meta Programming入門から応用まで](https://reader033.vdocuments.mx/reader033/viewer/2022051015/556a77dfd8b42a7c758b48da/html5/thumbnails/219.jpg)
// コンパイル時に計算可能template<class T>constexpr T add(T x, T y){
return x + y;}
見慣れた関数の形で実装出来る実行時にも共通のインタフェースで使える浮動小数点もOK
Template Meta Programming応用
![Page 220: Template Meta Programming入門から応用まで](https://reader033.vdocuments.mx/reader033/viewer/2022051015/556a77dfd8b42a7c758b48da/html5/thumbnails/220.jpg)
次のような式はconstant expressionsと呼ばれる。(Constant
expressionはコンパイル時に評価され得る)
constant-expression:conditional-expression
以降の条件部分はかなり細かいので、発表では適当に流すので各自確認しておいて欲しい
次ページ以降の条件に当てはまる場合、constexprにはなれない
Template Meta Programming応用
![Page 221: Template Meta Programming入門から応用まで](https://reader033.vdocuments.mx/reader033/viewer/2022051015/556a77dfd8b42a7c758b48da/html5/thumbnails/221.jpg)
条件
・this (非静的メンバ関数の本体に暗黙の変換の結果を含む、クラスメンバアクセス式の後置式、として表れていない場合)
・リテラルクラスのconstexprコンストラクタとconstexpr関数以外の関数呼び出し(オーバーロードの解決は普段通り適用される)
・constexpr関数やconstexprコンストラクタの定義の外での未定義動作のconstexpr関数や、未定義動作のconstexprコンストラクタの呼び出し
Template Meta Programming応用
![Page 222: Template Meta Programming入門から応用まで](https://reader033.vdocuments.mx/reader033/viewer/2022051015/556a77dfd8b42a7c758b48da/html5/thumbnails/222.jpg)
条件・constant expressionを生成しないような引数を用いてのconstexpr関数の呼び出し
例constexpr const int* addr(const int& ir) { return &ir; } // OK static const int x = 5;constexpr const int* xp = addr(x); // OK constant expressionなアドレスconstexpr const int* tp = addr(5); // エラー 一時アドレスの取得はconstant
expressionではない
Template Meta Programming応用
![Page 223: Template Meta Programming入門から応用まで](https://reader033.vdocuments.mx/reader033/viewer/2022051015/556a77dfd8b42a7c758b48da/html5/thumbnails/223.jpg)
条件・constant expressionを生成しないような引数による、初期化リストのみからなるconstexprコンストラクタの呼び出し
例int x; // not constantstruct A { constexpr A(bool b) : m(b?42:x) { } int m;};constexpr int v = A(true).m; // OKconstexpr int w = A(false).m; // エラー mの初期化に用いられるxが定数でない
Template Meta Programming応用
![Page 224: Template Meta Programming入門から応用まで](https://reader033.vdocuments.mx/reader033/viewer/2022051015/556a77dfd8b42a7c758b48da/html5/thumbnails/224.jpg)
条件・constexpr関数又はconstexprコンストラクタの再帰呼び出しが処理系の定義する制限を超える場合(Annex Bを参照)
Annex BにおいてRecursive constexpr function invocations [512].と定義されている・数学上定義されないような値、又は特定の型で扱える範囲外のその型の値。・ラムダ式・次の場合を除く左辺値から右辺値への変換 ・constant expressionで事前に初期化された非volatileなconstオブジェクトを参照する整数型のglvalue又はenum
・constexpr修飾で定義された、非volatileのオブジェクトかそのようなサブオブジェクトを参照するリテラル型のglvalue
・constant expressionで初期化された寿命の尽きていない一時オブジェクトを参照するリテラル型のglvalue
Template Meta Programming応用
![Page 225: Template Meta Programming入門から応用まで](https://reader033.vdocuments.mx/reader033/viewer/2022051015/556a77dfd8b42a7c758b48da/html5/thumbnails/225.jpg)
条件・非activeなunionのメンバやサブオブジェクトを参照するglvalueに適用される左辺値から右辺値への変換・constant expressionによって初期化されていない状態の値やデータメンバ参照を参照するid-expression
・dynamic cast
・reinterpret_cast
・擬似destructorの呼び出し・インクリメント及びデクリメント操作・多態クラス型に対するtypeid式・new式・delete式
Template Meta Programming応用
![Page 226: Template Meta Programming入門から応用まで](https://reader033.vdocuments.mx/reader033/viewer/2022051015/556a77dfd8b42a7c758b48da/html5/thumbnails/226.jpg)
条件・ポインタ同士の減算
・結果が不特定な場所での比較に関連するような演算子(rational or equality
operator)
・代入及び複合代入・throw式
Template Meta Programming応用
![Page 227: Template Meta Programming入門から応用まで](https://reader033.vdocuments.mx/reader033/viewer/2022051015/556a77dfd8b42a7c758b48da/html5/thumbnails/227.jpg)
更に補足実行時計算とコンパイル時計算の浮動小数点演算の精度は異なる場合がある
Template Meta Programming応用
![Page 228: Template Meta Programming入門から応用まで](https://reader033.vdocuments.mx/reader033/viewer/2022051015/556a77dfd8b42a7c758b48da/html5/thumbnails/228.jpg)
規格では浮動小数点の演算精度に関して制限を課さないので、コンパイル時と実行時における同じ式の浮動小数点演算の結果が同じである保証は無い(N3337 5.19 Constant expressions)
bool f() { char array[1 + int(1 + 0.2 - 0.1 - 0.1)]; // 必ずコンパイル時に計算される int size = 1 + int(1 + 0.2 - 0.1 - 0.1); // 実行時に計算されるかもしれない return sizeof(array) == size;}
f()の結果がtrueであるかfalseであるかは未定義である。
Template Meta Programming応用
![Page 229: Template Meta Programming入門から応用まで](https://reader033.vdocuments.mx/reader033/viewer/2022051015/556a77dfd8b42a7c758b48da/html5/thumbnails/229.jpg)
・整数演算しか出来ないTMPに比べ constexprは浮動小数点演算もコンパイル 時に出来る・コンパイル時計算にしか使えないTMPに比 べconstexprは実行時計算にも使える・逆に型に関する処理はTMPでしか実現出 来ない(TMPの独壇場)
Template Meta Programming応用
![Page 230: Template Meta Programming入門から応用まで](https://reader033.vdocuments.mx/reader033/viewer/2022051015/556a77dfd8b42a7c758b48da/html5/thumbnails/230.jpg)
補足decltype
Template Meta Programming応用
![Page 231: Template Meta Programming入門から応用まで](https://reader033.vdocuments.mx/reader033/viewer/2022051015/556a77dfd8b42a7c758b48da/html5/thumbnails/231.jpg)
decltypeイメージとしてはsizeofの型バージョン
Template Meta Programming応用
![Page 232: Template Meta Programming入門から応用まで](https://reader033.vdocuments.mx/reader033/viewer/2022051015/556a77dfd8b42a7c758b48da/html5/thumbnails/232.jpg)
decltypeThe type denoted by decltype(e) is defined as follows:— if e is an unparenthesized id-expression or an unparenthesized class member access (5.2.5), decltype(e) is the type of the entity named by e. If there is no such entity, or if e names a set of overloaded functions, the program is ill-formed;— otherwise, if e is an xvalue, decltype(e) is T&&, where T is the type of e;— otherwise, if e is an lvalue, decltype(e) is T&, where T is the type of e;— otherwise, decltype(e) is the type of e.
Template Meta Programming応用
![Page 233: Template Meta Programming入門から応用まで](https://reader033.vdocuments.mx/reader033/viewer/2022051015/556a77dfd8b42a7c758b48da/html5/thumbnails/233.jpg)
decltype
if e is an unparenthesized id-expression or an unparenthesized class member access ...
要するにexpressionが括弧で囲まれていないような
decltype(expression)の形のものの場合
Template Meta Programming応用
![Page 234: Template Meta Programming入門から応用まで](https://reader033.vdocuments.mx/reader033/viewer/2022051015/556a77dfd8b42a7c758b48da/html5/thumbnails/234.jpg)
例char a;decltype(a); // char
int b = 1;int& c = b;decltype(c); // int&
const int* d;decltype(d); // const int*
Template Meta Programming応用
![Page 235: Template Meta Programming入門から応用まで](https://reader033.vdocuments.mx/reader033/viewer/2022051015/556a77dfd8b42a7c758b48da/html5/thumbnails/235.jpg)
例struct a_type { using type = int; };
a_type a;decltype(a); // a_typedecltype(a)::type; // int
void f(int);decltype(f); // void (int)
Template Meta Programming応用
![Page 236: Template Meta Programming入門から応用まで](https://reader033.vdocuments.mx/reader033/viewer/2022051015/556a77dfd8b42a7c758b48da/html5/thumbnails/236.jpg)
例void f(int);void f(double);decltype(f); // Error
関数に複数のオーバーロードがあるとダメ
Template Meta Programming応用
![Page 237: Template Meta Programming入門から応用まで](https://reader033.vdocuments.mx/reader033/viewer/2022051015/556a77dfd8b42a7c758b48da/html5/thumbnails/237.jpg)
例int f();decltype(f()); // int
関数の戻り値の型も取れる
decltype(e)のeのexpressionが評価されることはないので関数の定義は必要ない(TMPにおいて重要)
Template Meta Programming応用
![Page 238: Template Meta Programming入門から応用まで](https://reader033.vdocuments.mx/reader033/viewer/2022051015/556a77dfd8b42a7c758b48da/html5/thumbnails/238.jpg)
decltypedecltype((expression))の形のものの場合
Template Meta Programming応用
![Page 239: Template Meta Programming入門から応用まで](https://reader033.vdocuments.mx/reader033/viewer/2022051015/556a77dfd8b42a7c758b48da/html5/thumbnails/239.jpg)
decltype
otherwise, if e is an xvalue, decltype(e) is T&&, where T is the type of e;
decltype((expression))のような括弧で囲まれたもので、かつxvalueの場合T&&になる
xvalueはrvalue referenceを返す関数の呼び出しとそれに準ずるもののイメージ(std::moveなども含まれる)
Template Meta Programming応用
![Page 240: Template Meta Programming入門から応用まで](https://reader033.vdocuments.mx/reader033/viewer/2022051015/556a77dfd8b42a7c758b48da/html5/thumbnails/240.jpg)
decltype
otherwise, if e is an lvalue, decltype(e) is T&, where T is the type of e;
decltype((expression))のような括弧で囲まれたもので、かつlvalueの場合T&になる
Template Meta Programming応用
![Page 241: Template Meta Programming入門から応用まで](https://reader033.vdocuments.mx/reader033/viewer/2022051015/556a77dfd8b42a7c758b48da/html5/thumbnails/241.jpg)
decltype
otherwise, decltype(e) is the type of e.
それ以外(prvalue等)はeの型
例decltype(1); // intdecltype("hello,world"); // const char[12]
Template Meta Programming応用
![Page 242: Template Meta Programming入門から応用まで](https://reader033.vdocuments.mx/reader033/viewer/2022051015/556a77dfd8b42a7c758b48da/html5/thumbnails/242.jpg)
decltypeまとめ・decltypeを使うとオブジェクトや関数の戻 り値の型を得る事が出来る・decltypeの結果は括弧の有無で変わる
Template Meta Programming応用
![Page 243: Template Meta Programming入門から応用まで](https://reader033.vdocuments.mx/reader033/viewer/2022051015/556a77dfd8b42a7c758b48da/html5/thumbnails/243.jpg)
補足SFINAE
Template Meta Programming応用
![Page 244: Template Meta Programming入門から応用まで](https://reader033.vdocuments.mx/reader033/viewer/2022051015/556a77dfd8b42a7c758b48da/html5/thumbnails/244.jpg)
SFINAESubstitution failure is not an error
Template Meta Programming応用
![Page 245: Template Meta Programming入門から応用まで](https://reader033.vdocuments.mx/reader033/viewer/2022051015/556a77dfd8b42a7c758b48da/html5/thumbnails/245.jpg)
テンプレートの置き換えに失敗してもすぐにはエラーにならず他の候補を探す
必修知識だがC++入門書には多分載ってない(結果として知らない人も居る印象)
Template Meta Programming応用
![Page 246: Template Meta Programming入門から応用まで](https://reader033.vdocuments.mx/reader033/viewer/2022051015/556a77dfd8b42a7c758b48da/html5/thumbnails/246.jpg)
言葉より実例を見るほうが早い
Template Meta Programming応用
![Page 247: Template Meta Programming入門から応用まで](https://reader033.vdocuments.mx/reader033/viewer/2022051015/556a77dfd8b42a7c758b48da/html5/thumbnails/247.jpg)
struct Test { typedef int foo;}; template <typename T> void f(typename T::foo) {} // Definition #1 template <typename T> void f(T) {} // Definition #2 int main() { f<Test>(10); f<int>(10); }
Template Meta Programming応用
![Page 248: Template Meta Programming入門から応用まで](https://reader033.vdocuments.mx/reader033/viewer/2022051015/556a77dfd8b42a7c758b48da/html5/thumbnails/248.jpg)
struct Test { typedef int foo;}; template <typename T> void f(typename T::foo) {} // Definition #1 template <typename T> void f(T) {} // Definition #2 int main() { f<Test>(10); f<int>(10); }
Template Meta Programming応用
![Page 249: Template Meta Programming入門から応用まで](https://reader033.vdocuments.mx/reader033/viewer/2022051015/556a77dfd8b42a7c758b48da/html5/thumbnails/249.jpg)
struct Test { typedef int foo;}; template <typename T> void f(typename T::foo) {} // Definition #1 template <typename T> void f(T) {} // Definition #2 int main() { f<Test>(10); f<int>(10); }
Template Meta Programming応用
![Page 250: Template Meta Programming入門から応用まで](https://reader033.vdocuments.mx/reader033/viewer/2022051015/556a77dfd8b42a7c758b48da/html5/thumbnails/250.jpg)
struct Test { typedef int foo;}; template <typename T> void f(typename T::foo) {} // Definition #1 定義にマッチする template <typename T> void f(T) {} // Definition #2 int main() { f<Test>(10); // Call #1. f<int>(10); }
Template Meta Programming応用
![Page 251: Template Meta Programming入門から応用まで](https://reader033.vdocuments.mx/reader033/viewer/2022051015/556a77dfd8b42a7c758b48da/html5/thumbnails/251.jpg)
struct Test { typedef int foo;}; template <typename T> void f(typename T::foo) {} // Definition #1 int::fooは存在しない template <typename T> void f(T) {} // Definition #2 int main() { f<Test>(10); // Call #1. f<int>(10); }
Template Meta Programming応用
![Page 252: Template Meta Programming入門から応用まで](https://reader033.vdocuments.mx/reader033/viewer/2022051015/556a77dfd8b42a7c758b48da/html5/thumbnails/252.jpg)
struct Test { typedef int foo;}; template <typename T> void f(typename T::foo) {} // Definition #1 呼出候補から外れる template <typename T> void f(T) {} // Definition #2 int main() { f<Test>(10); // Call #1. f<int>(10); }
Template Meta Programming応用
![Page 253: Template Meta Programming入門から応用まで](https://reader033.vdocuments.mx/reader033/viewer/2022051015/556a77dfd8b42a7c758b48da/html5/thumbnails/253.jpg)
struct Test { typedef int foo;}; template <typename T> void f(typename T::foo) {} // Definition #1 エラーにはならない template <typename T> void f(T) {} // Definition #2 定義にマッチする int main() { f<Test>(10); // Call #1. f<int>(10); // Call #2. }
Template Meta Programming応用
![Page 254: Template Meta Programming入門から応用まで](https://reader033.vdocuments.mx/reader033/viewer/2022051015/556a77dfd8b42a7c758b48da/html5/thumbnails/254.jpg)
このようなルールをSFINAEと呼ぶ条件分岐、エラーチェック等を実現出来る(例は後述)
Template Meta Programming応用
![Page 255: Template Meta Programming入門から応用まで](https://reader033.vdocuments.mx/reader033/viewer/2022051015/556a77dfd8b42a7c758b48da/html5/thumbnails/255.jpg)
1. 関連知識をおさえる2. 実践(有用なイディオムと例)
Template Meta Programming応用
![Page 256: Template Meta Programming入門から応用まで](https://reader033.vdocuments.mx/reader033/viewer/2022051015/556a77dfd8b42a7c758b48da/html5/thumbnails/256.jpg)
Template Meta Programming応用
関連知識をおさえたところでいよいよ応用として実用的なイディオム等を見ていく
![Page 257: Template Meta Programming入門から応用まで](https://reader033.vdocuments.mx/reader033/viewer/2022051015/556a77dfd8b42a7c758b48da/html5/thumbnails/257.jpg)
Template Meta Programming応用・Variadic templates 可変長引数テンプレートを扱う・enable_if SFINAEによる条件分岐・index_tuple, index_range (index_sequence) 整数列パラメータパックの生成と利用・Expression Template(ET)
式テンプレート
![Page 258: Template Meta Programming入門から応用まで](https://reader033.vdocuments.mx/reader033/viewer/2022051015/556a77dfd8b42a7c758b48da/html5/thumbnails/258.jpg)
Variadic templates 可変長引数テンプレートを扱う
Template Meta Programming応用
![Page 259: Template Meta Programming入門から応用まで](https://reader033.vdocuments.mx/reader033/viewer/2022051015/556a77dfd8b42a7c758b48da/html5/thumbnails/259.jpg)
要素の追加型リストを保持する単純なクラスtemplate<class... Types>struct list{
template<class Type>struct push_back{
using type = list<Types..., Type>; // これでOK
};};
Template Meta Programming応用
![Page 260: Template Meta Programming入門から応用まで](https://reader033.vdocuments.mx/reader033/viewer/2022051015/556a77dfd8b42a7c758b48da/html5/thumbnails/260.jpg)
要素の追加
例えばlist<int, char>::push_back<double>::typeのとき
Types...はint, charに展開され、Typeはdoubleであるから
list<Types..., Type>はlist<int, char, double>
Template Meta Programming応用
![Page 261: Template Meta Programming入門から応用まで](https://reader033.vdocuments.mx/reader033/viewer/2022051015/556a77dfd8b42a7c758b48da/html5/thumbnails/261.jpg)
要素の追加template<class... Types>struct list{
template<class Type>struct push_front{
using type = list<Type,Types...>; // これでOK
};};
push_frontも同様に可能
Template Meta Programming応用
![Page 262: Template Meta Programming入門から応用まで](https://reader033.vdocuments.mx/reader033/viewer/2022051015/556a77dfd8b42a7c758b48da/html5/thumbnails/262.jpg)
要素の削除template<class... Types>struct list{private:
template<class Type, class... Types2>struct pop_front_impl{
using type = list<Types2...>;};
public:struct pop_front { using type = typename pop_front_impl<Types...>::type; };
};
Template Meta Programming応用
![Page 263: Template Meta Programming入門から応用まで](https://reader033.vdocuments.mx/reader033/viewer/2022051015/556a77dfd8b42a7c758b48da/html5/thumbnails/263.jpg)
要素の削除
template<class Type, class... Types2>struct pop_front_impl{
using type = list<Types2...>;};
複数受け取ったパラメータのうちの最初の1つだけTypeに入り、残りは全てTypes2に入る
Template Meta Programming応用
![Page 264: Template Meta Programming入門から応用まで](https://reader033.vdocuments.mx/reader033/viewer/2022051015/556a77dfd8b42a7c758b48da/html5/thumbnails/264.jpg)
要素の削除pop_backだけは簡単にはいかない実装も他の操作に比べ面倒、計算コストもかかる
template<class... Types2, class Type> // エラー、可変長引数テンプレートはテンプレートパラメータのうち最後でなければならない
再帰的な実装など工夫が必要
Template Meta Programming応用
![Page 265: Template Meta Programming入門から応用まで](https://reader033.vdocuments.mx/reader033/viewer/2022051015/556a77dfd8b42a7c758b48da/html5/thumbnails/265.jpg)
enable_if SFINAEによる条件分岐
Template Meta Programming応用
![Page 266: Template Meta Programming入門から応用まで](https://reader033.vdocuments.mx/reader033/viewer/2022051015/556a77dfd8b42a7c758b48da/html5/thumbnails/266.jpg)
enable_if
・SFINAEを利用した条件分岐を手助けする イディオム・標準ライブラリにstd::enable_ifがある
Template Meta Programming応用
![Page 267: Template Meta Programming入門から応用まで](https://reader033.vdocuments.mx/reader033/viewer/2022051015/556a77dfd8b42a7c758b48da/html5/thumbnails/267.jpg)
enable_if
template<bool B, class T = void>struct enable_if {}; template<class T>struct enable_if<true, T> { typedef T type; };
つまり条件を満たした場合のみstd::enable_if<条件>::type
が定義される(SFINAEに利用出来る)
Template Meta Programming応用
![Page 268: Template Meta Programming入門から応用まで](https://reader033.vdocuments.mx/reader033/viewer/2022051015/556a77dfd8b42a7c758b48da/html5/thumbnails/268.jpg)
例template<class T>T foo2( T t, typename std::enable_if<std::is_integral<T>::value>::type* = 0) { return t;}
Tが整数型だった場合のみ呼び出し可能な関数Tが非整数型なら呼出候補から外される(もし呼出候補が1つも見つからなければコンパイルエラー)
不正な型の引数が渡される事を防止出来る
Template Meta Programming応用
![Page 269: Template Meta Programming入門から応用まで](https://reader033.vdocuments.mx/reader033/viewer/2022051015/556a77dfd8b42a7c758b48da/html5/thumbnails/269.jpg)
例template<class T, class Enable = void>class A; // undefined template<class T>class A<T, typename std::enable_if<std::is_floating_point<T>::value>::type> {};
条件を満たした場合のみ構築可能なクラスを部分特殊化で実現するSFINAEの対象は関数に限られたものではない
Template Meta Programming応用
![Page 270: Template Meta Programming入門から応用まで](https://reader033.vdocuments.mx/reader033/viewer/2022051015/556a77dfd8b42a7c758b48da/html5/thumbnails/270.jpg)
もっとenable_if enabler idiom
Template Meta Programming応用
![Page 271: Template Meta Programming入門から応用まで](https://reader033.vdocuments.mx/reader033/viewer/2022051015/556a77dfd8b42a7c758b48da/html5/thumbnails/271.jpg)
従来のenable_ifではオーバーロード出来ないtemplate<typename T, typename Enable = typename std::enable_if<std::is_integral<T>::value>::type>void f(T);
template<typename T, typename Enable = typename std::enable_if<std::is_pointer<T>::value>::type>void f(T); // デフォルト引数が異なるだけの再定義はダメ
Template Meta Programming応用
![Page 272: Template Meta Programming入門から応用まで](https://reader033.vdocuments.mx/reader033/viewer/2022051015/556a77dfd8b42a7c758b48da/html5/thumbnails/272.jpg)
type-parameterでのオーバーロードは厳しい
Template Meta Programming応用
![Page 273: Template Meta Programming入門から応用まで](https://reader033.vdocuments.mx/reader033/viewer/2022051015/556a77dfd8b42a7c758b48da/html5/thumbnails/273.jpg)
そこで以下のような宣言を行う
extern void * enabler;
Template Meta Programming応用
![Page 274: Template Meta Programming入門から応用まで](https://reader033.vdocuments.mx/reader033/viewer/2022051015/556a77dfd8b42a7c758b48da/html5/thumbnails/274.jpg)
extern void * enabler;
の定義は必要ない
enablerはextern修飾されているので外部リンケージを持つ
ということは
Template Meta Programming応用
![Page 275: Template Meta Programming入門から応用まで](https://reader033.vdocuments.mx/reader033/viewer/2022051015/556a77dfd8b42a7c758b48da/html5/thumbnails/275.jpg)
non-type template-parameterに渡せるもの
外部リンケージのあるオブジェクト・extern修飾されたもの
non-type template-parameter
![Page 276: Template Meta Programming入門から応用まで](https://reader033.vdocuments.mx/reader033/viewer/2022051015/556a77dfd8b42a7c758b48da/html5/thumbnails/276.jpg)
これはオーバーロード出来るtemplate<typename T, typename std::enable_if< std::is_integral<T>::value>::type *& = enabler>void f(T);
template<typename T, typename std::enable_if< std::is_pointer<T>::value>::type *& = enabler>void f(T);
Template Meta Programming応用
![Page 277: Template Meta Programming入門から応用まで](https://reader033.vdocuments.mx/reader033/viewer/2022051015/556a77dfd8b42a7c758b48da/html5/thumbnails/277.jpg)
template<typename T, typename std::enable_if< std::is_integral<T>::value>::type *& = enabler>void f(T);
enable_ifを非型パラメータとして用いているのがポイント(参照型は非型パラメータになれる)
enablerは外部リンケージを持つので非型パラメータに渡す事が出来る
Template Meta Programming応用
![Page 278: Template Meta Programming入門から応用まで](https://reader033.vdocuments.mx/reader033/viewer/2022051015/556a77dfd8b42a7c758b48da/html5/thumbnails/278.jpg)
わざわざ使わなくても十分なケースが多いしかし、必要になることもある
Template Meta Programming応用
![Page 279: Template Meta Programming入門から応用まで](https://reader033.vdocuments.mx/reader033/viewer/2022051015/556a77dfd8b42a7c758b48da/html5/thumbnails/279.jpg)
index_tuple, index_range (integer_sequence) 整数列パラメータパックの生成と利用
Template Meta Programming応用
![Page 280: Template Meta Programming入門から応用まで](https://reader033.vdocuments.mx/reader033/viewer/2022051015/556a77dfd8b42a7c758b48da/html5/thumbnails/280.jpg)
index_tuple idiomなどと呼ばれる・整数列のパラメータパックを生成するイ ディオム・C++14からはstd::integer_sequenceとして 同様の機能が標準ライブラリ入り・インデックスアクセス可能なデータ構造 の効率の良い要素の走査、リスト内包表 記相当の処理の実現
Template Meta Programming応用
![Page 281: Template Meta Programming入門から応用まで](https://reader033.vdocuments.mx/reader033/viewer/2022051015/556a77dfd8b42a7c758b48da/html5/thumbnails/281.jpg)
・整数列パラメータを保持する型・整数列パラメータを生成するヘルパメタ 関数のセットで用いられる
Template Meta Programming応用
![Page 282: Template Meta Programming入門から応用まで](https://reader033.vdocuments.mx/reader033/viewer/2022051015/556a77dfd8b42a7c758b48da/html5/thumbnails/282.jpg)
例えばNを正の整数としたとき
index_range<0, N>::typeがindex_tuple<0,1,2,3, ..., N-1>
と同じ型になるように実装する
Template Meta Programming応用
![Page 283: Template Meta Programming入門から応用まで](https://reader033.vdocuments.mx/reader033/viewer/2022051015/556a77dfd8b42a7c758b48da/html5/thumbnails/283.jpg)
実装例(簡単でクソなO(N)オーダーでの実装)template<std::size_t... Indices>
struct index_tuple {};
template<std::size_t step, std::size_t last, class result = index_tuple<>, bool flag = step
>= last>
struct index_range
{
using type = result;
};
template<std::size_t step, std::size_t last, std::size_t... Indices>
struct index_range<step, last, index_tuple<Indices...>, false>
: index_range<step + 1, last, index_tuple<Indices..., step>>
{};
Template Meta Programming応用
![Page 284: Template Meta Programming入門から応用まで](https://reader033.vdocuments.mx/reader033/viewer/2022051015/556a77dfd8b42a7c758b48da/html5/thumbnails/284.jpg)
実装例(簡単でクソなO(N)オーダーでの実装)template<std::size_t... Indices>
struct index_tuple {};
template<std::size_t step, std::size_t last, class result = index_tuple<>, bool flag = step
>= last>
struct index_range
{
using type = result;
};
template<std::size_t step, std::size_t last, std::size_t... Indices>
struct index_range<step, last, index_tuple<Indices...>, false>
: index_range<step + 1, last, index_tuple<Indices..., step>>
{};
Template Meta Programming応用
![Page 285: Template Meta Programming入門から応用まで](https://reader033.vdocuments.mx/reader033/viewer/2022051015/556a77dfd8b42a7c758b48da/html5/thumbnails/285.jpg)
template<std::size_t... Indices>struct index_tuple {};
整数列パラメータを保持する型
例index_tuple<0,1,2,3,4,5> // 0,1,2,3,4,5を保持
Template Meta Programming応用
![Page 286: Template Meta Programming入門から応用まで](https://reader033.vdocuments.mx/reader033/viewer/2022051015/556a77dfd8b42a7c758b48da/html5/thumbnails/286.jpg)
index_rangeは整数列パラメータを生成するヘルパメタ関数
・結果を返す定義(デフォルト定義)
・整数列パラメータを生成するフローの為 の部分特殊化
の2つの定義がある
Template Meta Programming応用
![Page 287: Template Meta Programming入門から応用まで](https://reader033.vdocuments.mx/reader033/viewer/2022051015/556a77dfd8b42a7c758b48da/html5/thumbnails/287.jpg)
実装例(簡単でクソなO(N)オーダーでの実装)template<std::size_t... Indices>
struct index_tuple {};
template<std::size_t step, std::size_t last, class result = index_tuple<>, bool flag = step
>= last>
struct index_range
{
using type = result;
};
template<std::size_t step, std::size_t last, std::size_t... Indices>
struct index_range<step, last, index_tuple<Indices...>, false>
: index_range<step + 1, last, index_tuple<Indices..., step>>
{};
Template Meta Programming応用
![Page 288: Template Meta Programming入門から応用まで](https://reader033.vdocuments.mx/reader033/viewer/2022051015/556a77dfd8b42a7c758b48da/html5/thumbnails/288.jpg)
結果を返すデフォルト定義template<std::size_t step,std::size_t last, class result = index_tuple<>,bool flag = first >= last>struct index_range{ using type = result;};
Template Meta Programming応用
![Page 289: Template Meta Programming入門から応用まで](https://reader033.vdocuments.mx/reader033/viewer/2022051015/556a77dfd8b42a7c758b48da/html5/thumbnails/289.jpg)
パラメータの解説template< std::size_t step, // 現在処理している数(呼出は初期値を渡す)
std::size_t last, // 範囲の終わり(さきほどのN)
class result = index_tuple<>, // 結果型(デフォでindex_tuple<>)
bool flag = first >= last // 再帰の終了条件>struct index_range{ using type = result; // 型を定義して結果を返す};
Template Meta Programming応用
![Page 290: Template Meta Programming入門から応用まで](https://reader033.vdocuments.mx/reader033/viewer/2022051015/556a77dfd8b42a7c758b48da/html5/thumbnails/290.jpg)
実装例(簡単でクソなO(N)オーダーでの実装)template<std::size_t... Indices>
struct index_tuple {};
template<std::size_t step, std::size_t last, class result = index_tuple<>, bool flag = step
>= last>
struct index_range
{
using type = result;
};
template<std::size_t step, std::size_t last, std::size_t... Indices>
struct index_range<step, last, index_tuple<Indices...>, false>
: index_range<step + 1, last, index_tuple<Indices..., step>>
{};
Template Meta Programming応用
![Page 291: Template Meta Programming入門から応用まで](https://reader033.vdocuments.mx/reader033/viewer/2022051015/556a77dfd8b42a7c758b48da/html5/thumbnails/291.jpg)
生成フローの定義template<std::size_t step, // 現在処理している数std::size_t last, // 範囲の終わりstd::size_t... Indices // 結果の整数列パラメータ>struct index_range<step,last,index_tuple<Indices...>,false> : index_range<step + 1, last, index_tuple<Indices..., step>>{};
Template Meta Programming応用
![Page 292: Template Meta Programming入門から応用まで](https://reader033.vdocuments.mx/reader033/viewer/2022051015/556a77dfd8b42a7c758b48da/html5/thumbnails/292.jpg)
生成フローの定義template<std::size_t step, // 現在処理している数std::size_t last, // 範囲の終わりstd::size_t... Indices // 結果の整数列パラメータ>struct index_range<step,last,index_tuple<Indices...>,false> // falseで特殊化: index_range<step + 1, last, index_tuple<Indices..., step>>{};
Template Meta Programming応用
![Page 293: Template Meta Programming入門から応用まで](https://reader033.vdocuments.mx/reader033/viewer/2022051015/556a77dfd8b42a7c758b48da/html5/thumbnails/293.jpg)
デフォルト定義における以下の部分bool flag = first >= last // 再帰の終了条件がfalseになったときだけ部分特殊化された定義が使われる
すなわち生成フローの定義が使われる
Template Meta Programming応用
![Page 294: Template Meta Programming入門から応用まで](https://reader033.vdocuments.mx/reader033/viewer/2022051015/556a77dfd8b42a7c758b48da/html5/thumbnails/294.jpg)
生成フローの定義template<std::size_t step, // 現在処理している数std::size_t last, // 範囲の終わりstd::size_t... Indices // 結果の整数列パラメータ>struct index_range<step,last,index_tuple<Indices...>, false> // falseで特殊化: index_range<step + 1, last, index_tuple<Indices..., step>>{};
Template Meta Programming応用
![Page 295: Template Meta Programming入門から応用まで](https://reader033.vdocuments.mx/reader033/viewer/2022051015/556a77dfd8b42a7c758b48da/html5/thumbnails/295.jpg)
生成フローの定義template<std::size_t step, // 現在処理している数std::size_t last, // 範囲の終わりstd::size_t... Indices // 結果の整数列パラメータ>struct index_range<step,last,index_tuple<Indices...>, // 結果型はindex_tupleにIndicesを渡すfalse> // falseで特殊化: index_range<step + 1, last, index_tuple<Indices..., step>>{};
Template Meta Programming応用
![Page 296: Template Meta Programming入門から応用まで](https://reader033.vdocuments.mx/reader033/viewer/2022051015/556a77dfd8b42a7c758b48da/html5/thumbnails/296.jpg)
template<
std::size_t step, // 現在処理している数std::size_t last, // 範囲の終わりstd::size_t... Indices // 結果の整数列パラメータ>
struct index_range<
step,
last,
index_tuple<Indices...>, // 結果型はindex_tupleにIndices渡すfalse> // falseで特殊化
: index_range<step + 1, last, index_tuple<Indices..., step>>// パラメータ違いのindex_rangeを継承している{};
Template Meta Programming応用
![Page 297: Template Meta Programming入門から応用まで](https://reader033.vdocuments.mx/reader033/viewer/2022051015/556a77dfd8b42a7c758b48da/html5/thumbnails/297.jpg)
テンプレートパラメータ違いの自分自身を継承すること
: index_range<step + 1, last, index_tuple<Indices..., step>>
メタ関数における再帰を意味する
テンプレートパラメータは関数の引数相当
Template Meta Programming応用
![Page 298: Template Meta Programming入門から応用まで](https://reader033.vdocuments.mx/reader033/viewer/2022051015/556a77dfd8b42a7c758b48da/html5/thumbnails/298.jpg)
: index_range<step + 1, last, index_tuple<Indices..., step>>
この部分ではstepを1進め可変長引数テンプレートパラメータの要素にstepを追加して再帰する
index_tupleに渡す引数を増やしながら再帰している
Template Meta Programming応用
![Page 299: Template Meta Programming入門から応用まで](https://reader033.vdocuments.mx/reader033/viewer/2022051015/556a77dfd8b42a7c758b48da/html5/thumbnails/299.jpg)
結果を返すデフォルト定義に戻るtemplate<std::size_t step,std::size_t last, class result = index_tuple<>, // (index_tuple<Indices..., step>)bool flag = first >= last// stepがlastに達した時点で再帰が止まる>struct index_range{ using type = result; // 結果型};
Template Meta Programming応用
![Page 300: Template Meta Programming入門から応用まで](https://reader033.vdocuments.mx/reader033/viewer/2022051015/556a77dfd8b42a7c758b48da/html5/thumbnails/300.jpg)
実用例
Template Meta Programming応用
![Page 301: Template Meta Programming入門から応用まで](https://reader033.vdocuments.mx/reader033/viewer/2022051015/556a77dfd8b42a7c758b48da/html5/thumbnails/301.jpg)
配列クラスと値nを受けとり、全要素にnを加えた値の要素を持つ配列クラスを返す関数iota
template<class T, std::size_t N, std::size_t... Indices>constexpr auto iota_impl(const array<T, N> arr, const T n, index_tuple<Indices...>)-> array<T, N> { return array<T, N>{{(arr[Indices] + n)...}};}
template<class T, std::size_t N>constexpr auto iota(const array<T, N> arr, const T n) -> array<T, N> { return iota_impl(arr, n, typename index_range<0, N>::type());}
constexpr array<int, 9> arr1{{1,2,3,4,5,6,7,8,9}}; // 配列クラスのオブジェクト
constexpr auto arr2 = iota(arr1, 1); // iotaには配列クラスのオブジェクトと値nを渡してやる//結果としてarray<int, 9>{{2,3,4,5,6,7,8,9,10}}が欲しい
Template Meta Programming応用
![Page 302: Template Meta Programming入門から応用まで](https://reader033.vdocuments.mx/reader033/viewer/2022051015/556a77dfd8b42a7c758b48da/html5/thumbnails/302.jpg)
template<class T, std::size_t N, std::size_t... Indices>constexpr auto iota_impl(const array<T, N> arr, const T n, index_tuple<Indices...>)-> array<T, N> { return array<T, N>{{(arr[Indices] + n)...}};}
template<class T, std::size_t N>constexpr auto iota(const array<T, N> arr, const T n) -> array<T, N> { return iota_impl(arr, n, typename index_range<0, N>::type());}
constexpr array<int, 9> arr1{{1,2,3,4,5,6,7,8,9}};constexpr auto arr2 = iota(arr1, 1); // array<int, 9>{{2,3,4,5,6,7,8,9,10}}
Tはintに、Nは9に推論される
Template Meta Programming応用
![Page 303: Template Meta Programming入門から応用まで](https://reader033.vdocuments.mx/reader033/viewer/2022051015/556a77dfd8b42a7c758b48da/html5/thumbnails/303.jpg)
template<class T, std::size_t N, std::size_t... Indices>constexpr auto iota_impl(const array<T, N> arr, const T n, index_tuple<Indices...>)-> array<T, N> { return array<T, N>{{(arr[Indices] + n)...}};}
template<class T, std::size_t N>constexpr auto iota(const array<T, N> arr, const T n) -> array<T, N> { return iota_impl(arr, n, typename index_range<0, N>::type());}
constexpr array<int, 9> arr1{{1,2,3,4,5,6,7,8,9}};constexpr auto arr2 = iota(arr1, 1); // array<int, 9>{{2,3,4,5,6,7,8,9,10}}
この場合N = 9であるからindex_range<0, 9>::typeになる
Template Meta Programming応用
![Page 304: Template Meta Programming入門から応用まで](https://reader033.vdocuments.mx/reader033/viewer/2022051015/556a77dfd8b42a7c758b48da/html5/thumbnails/304.jpg)
template<class T, std::size_t N, std::size_t... Indices>constexpr auto iota_impl(const array<T, N> arr, const T n, index_tuple<Indices...>)-> array<T, N> { return array<T, N>{{(arr[Indices] + n)...}};}
template<class T, std::size_t N>constexpr auto iota(const array<T, N> arr, const T n) -> array<T, N> { return iota_impl(arr, n, typename index_range<0, N>::type());}
constexpr array<int, 9> arr1{{1,2,3,4,5,6,7,8,9}};constexpr auto arr2 = iota(arr1, 1); // array<int, 9>{{2,3,4,5,6,7,8,9,10}}
index_range<0, 9>::typeはindex_tuple<0,1,2,3,4,5,6,7,8>である
Template Meta Programming応用
![Page 305: Template Meta Programming入門から応用まで](https://reader033.vdocuments.mx/reader033/viewer/2022051015/556a77dfd8b42a7c758b48da/html5/thumbnails/305.jpg)
template<class T, std::size_t N, std::size_t... Indices>constexpr auto iota_impl(const array<T, N> arr, const T n, index_tuple<Indices...>)-> array<T, N> { return array<T, N>{{(arr[Indices] + n)...}};}
template<class T, std::size_t N>constexpr auto iota(const array<T, N> arr, const T n) -> array<T, N> { return iota_impl(arr, n, typename index_range<0, N>::type());}
constexpr array<int, 9> arr1{{1,2,3,4,5,6,7,8,9}};constexpr auto arr2 = iota(arr1, 1); // array<int, 9>{{2,3,4,5,6,7,8,9,10}}
結果としてindex_tuple<0,1,2,3,4,5,6,7,8>()がiota_implの引数として渡される
Template Meta Programming応用
![Page 306: Template Meta Programming入門から応用まで](https://reader033.vdocuments.mx/reader033/viewer/2022051015/556a77dfd8b42a7c758b48da/html5/thumbnails/306.jpg)
template<class T, std::size_t N, std::size_t... Indices> // Indices is 0,1,2,3,4,5,6,7,8constexpr auto iota_impl(const array<T, N> arr, const T n, index_tuple<Indices...>)-> array<T, N> { return array<T, N>{{(arr[Indices] + n)...}};}
template<class T, std::size_t N>constexpr auto iota(const array<T, N> arr, const T n) -> array<T, N> { return iota_impl(arr, n, typename index_range<0, N>::type());}
constexpr array<int, 9> arr1{{1,2,3,4,5,6,7,8,9}};constexpr auto arr2 = iota(arr1, 1); // array<int, 9>{{2,3,4,5,6,7,8,9,10}}
このときIndicesは0,1,2,3,4,5,6,7,8に推論される
Template Meta Programming応用
![Page 307: Template Meta Programming入門から応用まで](https://reader033.vdocuments.mx/reader033/viewer/2022051015/556a77dfd8b42a7c758b48da/html5/thumbnails/307.jpg)
template<class T, std::size_t N, std::size_t... Indices> // Indices is 0,1,2,3,4,5,6,7,8constexpr auto iota_impl(const array<T, N> arr, const T n, index_tuple<Indices...>)-> array<T, N> { return array<T, N>{{(arr[Indices] + n)...}};}
template<class T, std::size_t N>constexpr auto iota(const array<T, N> arr, const T n) -> array<T, N> { return iota_impl(arr, n, typename index_range<0, N>::type());}
constexpr array<int, 9> arr1{{1,2,3,4,5,6,7,8,9}};constexpr auto arr2 = iota(arr1, 1); // array<int, 9>{{2,3,4,5,6,7,8,9,10}}
最終的にarray<T, N>{{(arr[Indices] + n)...}}の部分はarray<int, 9>{{arr[0] + n, arr[1] + n, (中略)..., arr[8] + n}}
という風に展開される
Template Meta Programming応用
![Page 308: Template Meta Programming入門から応用まで](https://reader033.vdocuments.mx/reader033/viewer/2022051015/556a77dfd8b42a7c758b48da/html5/thumbnails/308.jpg)
基本的にインデックスアクセス可能なデータ構造であれば適用出来る
Template Meta Programming応用
![Page 309: Template Meta Programming入門から応用まで](https://reader033.vdocuments.mx/reader033/viewer/2022051015/556a77dfd8b42a7c758b48da/html5/thumbnails/309.jpg)
余談生成結果のメモ化
Template Meta Programming応用
![Page 310: Template Meta Programming入門から応用まで](https://reader033.vdocuments.mx/reader033/viewer/2022051015/556a77dfd8b42a7c758b48da/html5/thumbnails/310.jpg)
template<std::size_t First, std::size_t Last>struct index_tuple_memo{ static constexpr auto value = typename index_range<First, Last>::type();};
index_tuple系の生成結果のメモ化を行う試みtypename index_range::type()の呼び出し時にindex_tuple_memo::valueを代わりに使う事で使いまわす2回目以降の呼び出しでO(1)が期待出来る
Template Meta Programming応用
![Page 311: Template Meta Programming入門から応用まで](https://reader033.vdocuments.mx/reader033/viewer/2022051015/556a77dfd8b42a7c758b48da/html5/thumbnails/311.jpg)
・メモリ使用量が増える可能性・コンパイラの最適化によっては無意味 ・逆効果かも
同じ要素数で尚且つ数千要素のtuple展開を何度も行うような場合には有効かもしれないが通常は使わなくて良さそう
Template Meta Programming応用
![Page 312: Template Meta Programming入門から応用まで](https://reader033.vdocuments.mx/reader033/viewer/2022051015/556a77dfd8b42a7c758b48da/html5/thumbnails/312.jpg)
index_rangeの実装には簡単でクソなO(N)オーダーでの実装の他に有用なO(log2(N))オーダーでの実装法も知られている
Template Meta Programming応用
![Page 313: Template Meta Programming入門から応用まで](https://reader033.vdocuments.mx/reader033/viewer/2022051015/556a77dfd8b42a7c758b48da/html5/thumbnails/313.jpg)
線形オーダーでは扱える要素数が限られ、生成速度も遅い
のでSproutや標準ライブラリで後者の実装が使われている
Template Meta Programming応用
![Page 314: Template Meta Programming入門から応用まで](https://reader033.vdocuments.mx/reader033/viewer/2022051015/556a77dfd8b42a7c758b48da/html5/thumbnails/314.jpg)
アイデア概要
例えばN = 14のときIndicesが0,1,2,3,4,5,6であればindex_tuple<Indices..., (Indices + N/2)...> を展開すればindex_tuple<0,1,2,3,4,5,6,7,8,9,10,11,12,13> が得られる
現実には実装はもっと面倒だが基本的には、このように前の結果を利用して要素数を倍々にしていくという考え
Template Meta Programming応用
![Page 315: Template Meta Programming入門から応用まで](https://reader033.vdocuments.mx/reader033/viewer/2022051015/556a77dfd8b42a7c758b48da/html5/thumbnails/315.jpg)
詳しい実装に関してはsprout::index_rangeなどを見て欲しい
Template Meta Programming応用
![Page 316: Template Meta Programming入門から応用まで](https://reader033.vdocuments.mx/reader033/viewer/2022051015/556a77dfd8b42a7c758b48da/html5/thumbnails/316.jpg)
Expression Template(ET)式テンプレート
Template Meta Programming応用
![Page 317: Template Meta Programming入門から応用まで](https://reader033.vdocuments.mx/reader033/viewer/2022051015/556a77dfd8b42a7c758b48da/html5/thumbnails/317.jpg)
・式の評価を遅延させる・余計な一時オブジェクトの生成とコピーの 発生を防ぐ
Template Meta Programming応用
![Page 318: Template Meta Programming入門から応用まで](https://reader033.vdocuments.mx/reader033/viewer/2022051015/556a77dfd8b42a7c758b48da/html5/thumbnails/318.jpg)
通常、巨大な行列の一時オブジェクトが生成される演算に対して、演算の結果ではなく演算を表す型オブジェクトを返す
Template Meta Programming応用
![Page 319: Template Meta Programming入門から応用まで](https://reader033.vdocuments.mx/reader033/viewer/2022051015/556a77dfd8b42a7c758b48da/html5/thumbnails/319.jpg)
行列のA, B, Cの和A + B + C
ETを使わない実装では、A + Bで値を計算して一時オブジェクトを生成、更に一時オブジェクト + Cで値を計算して一時オブジェクトを生成という事が起こりうるその過程で巨大なオブジェクトのコピー、構築が起こりうる
Template Meta Programming応用
![Page 320: Template Meta Programming入門から応用まで](https://reader033.vdocuments.mx/reader033/viewer/2022051015/556a77dfd8b42a7c758b48da/html5/thumbnails/320.jpg)
行列のA, B, Cの和Plus<Plus<Vector<A>, Vector<B>>, Vector<C>>
演算を型として表す、巨大な行列をコピーしたりしなくて済むので、途中式の段階で一時オブジェクトの生成コストが非常に小さくなる
Template Meta Programming応用
![Page 321: Template Meta Programming入門から応用まで](https://reader033.vdocuments.mx/reader033/viewer/2022051015/556a77dfd8b42a7c758b48da/html5/thumbnails/321.jpg)
値はoperator=()が呼ばれた時に初めて評価される
Template Meta Programming応用
![Page 322: Template Meta Programming入門から応用まで](https://reader033.vdocuments.mx/reader033/viewer/2022051015/556a77dfd8b42a7c758b48da/html5/thumbnails/322.jpg)
参考ETの簡単な実装法やデメリット等も含めて紹介されている
日本で一番分かりやすく書いたつもりのExpression Templateの説明http://d.hatena.ne.jp/Cryolite/20040506
などが分かりやすい
Template Meta Programming応用
![Page 323: Template Meta Programming入門から応用まで](https://reader033.vdocuments.mx/reader033/viewer/2022051015/556a77dfd8b42a7c758b48da/html5/thumbnails/323.jpg)
おしながき
1. Templateの基本確認2. Template Meta Programmingとは3. Template Meta Programming入門4. Template Meta Programming応用5. その他付録6. まとめ7. 質疑応答
![Page 324: Template Meta Programming入門から応用まで](https://reader033.vdocuments.mx/reader033/viewer/2022051015/556a77dfd8b42a7c758b48da/html5/thumbnails/324.jpg)
その他付録
1. TMPとは直接関係ないイディオムなど2. これからのTMPと関連イディオムなど
![Page 325: Template Meta Programming入門から応用まで](https://reader033.vdocuments.mx/reader033/viewer/2022051015/556a77dfd8b42a7c758b48da/html5/thumbnails/325.jpg)
その他付録
型を受け取るユーザ定義リテラル
![Page 326: Template Meta Programming入門から応用まで](https://reader033.vdocuments.mx/reader033/viewer/2022051015/556a77dfd8b42a7c758b48da/html5/thumbnails/326.jpg)
その他付録
整数リテラルと浮動小数点リテラルに限りchar...のテンプレート実引数として受け取ることが出来る
![Page 327: Template Meta Programming入門から応用まで](https://reader033.vdocuments.mx/reader033/viewer/2022051015/556a77dfd8b42a7c758b48da/html5/thumbnails/327.jpg)
その他付録
template<char...>void operator "" _to_string() {};
12345_to_string; // template<‘1’,’2’,’3’,’4’,’5’>として渡される
3.14_to_string; // template<‘3’,’.’,’1’,,4>
![Page 328: Template Meta Programming入門から応用まで](https://reader033.vdocuments.mx/reader033/viewer/2022051015/556a77dfd8b42a7c758b48da/html5/thumbnails/328.jpg)
その他付録#include <sprout/index_tuple.hpp>
template<char last>constexpr auto indices()-> typename sprout::index_range<0, last - '0'>::type { return sprout::index_range<0, last - '0'>::make();}
template<char... last>constexpr auto operator "" _indices() -> decltype(indices<last...>()) { static_assert(sizeof...(last) == 1, ""); return indices<last...>();}
int main() { static_assert(std::is_same<decltype(2_indices), sprout::index_tuple<0,1>>::value, "");}
ユーザ定義リテラルを使ったindex_tupleの生成みたいなサンプル(実際にはchar同士の減算等にはもう少し気を配った方がいい感じがしますが)
![Page 329: Template Meta Programming入門から応用まで](https://reader033.vdocuments.mx/reader033/viewer/2022051015/556a77dfd8b42a7c758b48da/html5/thumbnails/329.jpg)
その他付録
型文字列の生成に使えるただし整数と浮動小数点のみ
ショージキ微妙だが今後に期待
![Page 330: Template Meta Programming入門から応用まで](https://reader033.vdocuments.mx/reader033/viewer/2022051015/556a77dfd8b42a7c758b48da/html5/thumbnails/330.jpg)
その他付録
private namespace idiom detail等へのアクセスを制限する
![Page 331: Template Meta Programming入門から応用まで](https://reader033.vdocuments.mx/reader033/viewer/2022051015/556a77dfd8b42a7c758b48da/html5/thumbnails/331.jpg)
その他付録namespace tmp { namespace { // 無名名前空間 namespace detail { // detailへはアクセスされたくない void f_impl() {} // privateな実装 } void f() { detail::f_impl(); } // publicなインタフェース } namespace detail {}; // detailのメンバへのアクセスを殺す} tmp::f(); // OK tmp::detail::f_impl(); // ルックアップに失敗しエラー
![Page 332: Template Meta Programming入門から応用まで](https://reader033.vdocuments.mx/reader033/viewer/2022051015/556a77dfd8b42a7c758b48da/html5/thumbnails/332.jpg)
その他付録
無名名前空間が暗黙にusingされる事を逆手に取る
detailへのアクセスを殺せるので名前空間スコープで、メタ関数の内部実装にどうしてもアクセスされたくない場合には有効
![Page 333: Template Meta Programming入門から応用まで](https://reader033.vdocuments.mx/reader033/viewer/2022051015/556a77dfd8b42a7c758b48da/html5/thumbnails/333.jpg)
その他付録
1. TMPとは直接関係ないイディオムなど2. これからのTMPと関連イディオムなど
![Page 334: Template Meta Programming入門から応用まで](https://reader033.vdocuments.mx/reader033/viewer/2022051015/556a77dfd8b42a7c758b48da/html5/thumbnails/334.jpg)
その他付録
先程取り上げたinteger_sequenceの他にもある、C++14(所謂N3690辺り) / C++1y以降に入ると思われる機能とそれに関連する話(大雑把に未来の話です)
ただしTMPに割と関連しそうなものだけ
![Page 335: Template Meta Programming入門から応用まで](https://reader033.vdocuments.mx/reader033/viewer/2022051015/556a77dfd8b42a7c758b48da/html5/thumbnails/335.jpg)
その他付録
C++14以降で(ほぼ確実に)入る機能
![Page 336: Template Meta Programming入門から応用まで](https://reader033.vdocuments.mx/reader033/viewer/2022051015/556a77dfd8b42a7c758b48da/html5/thumbnails/336.jpg)
その他付録
constexprの制限緩和
![Page 337: Template Meta Programming入門から応用まで](https://reader033.vdocuments.mx/reader033/viewer/2022051015/556a77dfd8b42a7c758b48da/html5/thumbnails/337.jpg)
その他付録
・副作用、制御構文が使えるようになる・ポインタ同士の減算が定数式になるなど
一部制限が増えている・a conversion from type cv void * to a pointer-to-object type;
C++11ではreinterpret_castが禁止されていたのにvoid*の型変換が禁止されていなかったが、これもダメに修正された
![Page 338: Template Meta Programming入門から応用まで](https://reader033.vdocuments.mx/reader033/viewer/2022051015/556a77dfd8b42a7c758b48da/html5/thumbnails/338.jpg)
その他付録
ただし、constexpr関数では相変わらずエラーハンドリングが困難なので迂闊に副作用の濫用を行うと、例外安全性を保つのが難しいので注意が必要
その他、細かい事は規格等を参照して欲しい
![Page 339: Template Meta Programming入門から応用まで](https://reader033.vdocuments.mx/reader033/viewer/2022051015/556a77dfd8b42a7c758b48da/html5/thumbnails/339.jpg)
その他付録
decltype(auto)
![Page 340: Template Meta Programming入門から応用まで](https://reader033.vdocuments.mx/reader033/viewer/2022051015/556a77dfd8b42a7c758b48da/html5/thumbnails/340.jpg)
その他付録
decltype(auto)は、式をdecltype()の中に書いたのと同じ挙動になる
![Page 341: Template Meta Programming入門から応用まで](https://reader033.vdocuments.mx/reader033/viewer/2022051015/556a77dfd8b42a7c758b48da/html5/thumbnails/341.jpg)
その他付録
江添さんの記事が分かりやすいhttp://cpplover.blogspot.jp/2013/08/decltypeauto.html
![Page 342: Template Meta Programming入門から応用まで](https://reader033.vdocuments.mx/reader033/viewer/2022051015/556a77dfd8b42a7c758b48da/html5/thumbnails/342.jpg)
その他付録記事の例のみ引用する
int i = 0 ;int && f() ;
auto a1 = i ; // intdecltype(auto) a2 = i ; // int
auto b1 = (i) ; // intdecltype(auto) b2 = (i) ; // int &
auto c1 = f() ; // intdecltype(auto) c2 = f() ; // int &&
![Page 343: Template Meta Programming入門から応用まで](https://reader033.vdocuments.mx/reader033/viewer/2022051015/556a77dfd8b42a7c758b48da/html5/thumbnails/343.jpg)
その他付録
関数の戻り値などに利用出来る
template < typename T, typename U >auto g( T const & t, U const & u )-> decltype( auto ) // decltype( f( t, u ) )と書かなくて済む{ return f( t, u ) ;}
![Page 344: Template Meta Programming入門から応用まで](https://reader033.vdocuments.mx/reader033/viewer/2022051015/556a77dfd8b42a7c758b48da/html5/thumbnails/344.jpg)
その他付録
ジェネリックラムダ
![Page 345: Template Meta Programming入門から応用まで](https://reader033.vdocuments.mx/reader033/viewer/2022051015/556a77dfd8b42a7c758b48da/html5/thumbnails/345.jpg)
その他付録
ラムダ式もテンプレート化出来るauto NumElements = []<int N>(auto (&a)[N]) { return N; };
![Page 346: Template Meta Programming入門から応用まで](https://reader033.vdocuments.mx/reader033/viewer/2022051015/556a77dfd8b42a7c758b48da/html5/thumbnails/346.jpg)
その他付録
Variable Templates 変数テンプレート
![Page 347: Template Meta Programming入門から応用まで](https://reader033.vdocuments.mx/reader033/viewer/2022051015/556a77dfd8b42a7c758b48da/html5/thumbnails/347.jpg)
その他付録
読んで字の如く、変数をテンプレート化する
![Page 348: Template Meta Programming入門から応用まで](https://reader033.vdocuments.mx/reader033/viewer/2022051015/556a77dfd8b42a7c758b48da/html5/thumbnails/348.jpg)
その他付録
変数テンプレートtemplate<class T>constexpr T pi = static_cast<T>(3.14);
pi<int> == 3;pi<float> == 3.14;
異なる精度の値を得る
![Page 349: Template Meta Programming入門から応用まで](https://reader033.vdocuments.mx/reader033/viewer/2022051015/556a77dfd8b42a7c758b48da/html5/thumbnails/349.jpg)
その他付録
変数テンプレートtemplate<class T1, T2>constexpr bool is_same_v = std::is_same<T1, T2>::value;
is_same_v<int, double>; // false
面倒な::valueを書かずに済む
![Page 350: Template Meta Programming入門から応用まで](https://reader033.vdocuments.mx/reader033/viewer/2022051015/556a77dfd8b42a7c758b48da/html5/thumbnails/350.jpg)
その他付録
C++1y(ここではC++14よりも後を意味する)
以降で入るかもしれない提案
![Page 351: Template Meta Programming入門から応用まで](https://reader033.vdocuments.mx/reader033/viewer/2022051015/556a77dfd8b42a7c758b48da/html5/thumbnails/351.jpg)
その他付録
Concepts Lite 軽量コンセプト
![Page 352: Template Meta Programming入門から応用まで](https://reader033.vdocuments.mx/reader033/viewer/2022051015/556a77dfd8b42a7c758b48da/html5/thumbnails/352.jpg)
その他付録
C++11入りする予定だったConceptの軽量・改良版
幾つかペーパーのようなものが出ている模様
![Page 353: Template Meta Programming入門から応用まで](https://reader033.vdocuments.mx/reader033/viewer/2022051015/556a77dfd8b42a7c758b48da/html5/thumbnails/353.jpg)
その他付録
プログラマにやさしい構文で型制約を行えるようになる
constexpr関数として型制約を定義する案など
使えるようになるのは当分先の話になりそうな気はします
![Page 354: Template Meta Programming入門から応用まで](https://reader033.vdocuments.mx/reader033/viewer/2022051015/556a77dfd8b42a7c758b48da/html5/thumbnails/354.jpg)
その他付録
N3741Opaque Alias
![Page 355: Template Meta Programming入門から応用まで](https://reader033.vdocuments.mx/reader033/viewer/2022051015/556a77dfd8b42a7c758b48da/html5/thumbnails/355.jpg)
その他付録
Strong typedef ある型から別の型を作る
using identifier = access-specifier type-id opaque-definition
![Page 356: Template Meta Programming入門から応用まで](https://reader033.vdocuments.mx/reader033/viewer/2022051015/556a77dfd8b42a7c758b48da/html5/thumbnails/356.jpg)
その他付録
using age = private int; // intとは別の型として認識される// privateにより暗黙のキャストは許可しない
age age1 = static_cast<age>(20); // 明示的なキャストをするage age2 = 18; // Error ageはintではない
これまでのtypedefやusingではこのような事は出来ない
![Page 357: Template Meta Programming入門から応用まで](https://reader033.vdocuments.mx/reader033/viewer/2022051015/556a77dfd8b42a7c758b48da/html5/thumbnails/357.jpg)
その他付録
オーバーロード等も有効になる
int f(int);age f(age);
別物として扱われる
![Page 358: Template Meta Programming入門から応用まで](https://reader033.vdocuments.mx/reader033/viewer/2022051015/556a77dfd8b42a7c758b48da/html5/thumbnails/358.jpg)
その他付録
N3730Specializations and namespaces
![Page 359: Template Meta Programming入門から応用まで](https://reader033.vdocuments.mx/reader033/viewer/2022051015/556a77dfd8b42a7c758b48da/html5/thumbnails/359.jpg)
その他付録
ネストされた名前空間を閉じなくても特殊化を書けるようにする提案
![Page 360: Template Meta Programming入門から応用まで](https://reader033.vdocuments.mx/reader033/viewer/2022051015/556a77dfd8b42a7c758b48da/html5/thumbnails/360.jpg)
その他付録namespace A { namespace B { /* ... */ class C { /* ... */ }; }} // 一度名前空間を抜ける
namespace std { template<> // 特殊化を書く struct hash<A::B::C> { size_t operator()(A::B::C const &c) { /* ... */ } };}
namespace A { /* Reenter namespace I am using */ namespace B { /* ... */ }}
![Page 361: Template Meta Programming入門から応用まで](https://reader033.vdocuments.mx/reader033/viewer/2022051015/556a77dfd8b42a7c758b48da/html5/thumbnails/361.jpg)
その他付録namespace A { namespace B { /* ... */ class C { /* ... */ }; template<> struct ::std::hash<C> { std::size_t operator()(C const &c) { /* ... */ } }; /* ... */ }}
このように書けるようになる
![Page 362: Template Meta Programming入門から応用まで](https://reader033.vdocuments.mx/reader033/viewer/2022051015/556a77dfd8b42a7c758b48da/html5/thumbnails/362.jpg)
その他付録
N3728Packaging Parameter Packs
![Page 363: Template Meta Programming入門から応用まで](https://reader033.vdocuments.mx/reader033/viewer/2022051015/556a77dfd8b42a7c758b48da/html5/thumbnails/363.jpg)
その他付録
パラメータパックを保持するための型リストをサポートする提案
パラメータパックが間違いなく扱いやすくなる
具体例はN3728ペーパー参照
![Page 364: Template Meta Programming入門から応用まで](https://reader033.vdocuments.mx/reader033/viewer/2022051015/556a77dfd8b42a7c758b48da/html5/thumbnails/364.jpg)
その他付録
N3413Allowing arbitrary literal types for non-type template parameters
![Page 365: Template Meta Programming入門から応用まで](https://reader033.vdocuments.mx/reader033/viewer/2022051015/556a77dfd8b42a7c758b48da/html5/thumbnails/365.jpg)
その他付録
非型パラメータとして任意のリテラル型を許容しようという提案
![Page 366: Template Meta Programming入門から応用まで](https://reader033.vdocuments.mx/reader033/viewer/2022051015/556a77dfd8b42a7c758b48da/html5/thumbnails/366.jpg)
その他付録struct C { constexpr C(int v) : v(v) { } int v;};
template<C c> // !?struct X { int array[c.v];};
int main(){ X<C(42)> x;} C++の世界の法則が乱れる完全にヤバい提案
![Page 367: Template Meta Programming入門から応用まで](https://reader033.vdocuments.mx/reader033/viewer/2022051015/556a77dfd8b42a7c758b48da/html5/thumbnails/367.jpg)
その他付録
N3761Proposing type_at<>
![Page 368: Template Meta Programming入門から応用まで](https://reader033.vdocuments.mx/reader033/viewer/2022051015/556a77dfd8b42a7c758b48da/html5/thumbnails/368.jpg)
その他付録
パラメータパックのN番目の要素にアクセスする機能のメタ関数を標準に入れる提案
![Page 369: Template Meta Programming入門から応用まで](https://reader033.vdocuments.mx/reader033/viewer/2022051015/556a77dfd8b42a7c758b48da/html5/thumbnails/369.jpg)
その他付録簡単な実装案が書かれている要するにN番目の要素に到達するまで線形再帰する
template <unsigned N, typename T, typename ...R>struct type_at { using type = typename type_at<N - 1, R...>::type;};
template <typename T, typename ...R>struct type_at<0, T, R...> { using type = T;};
![Page 370: Template Meta Programming入門から応用まで](https://reader033.vdocuments.mx/reader033/viewer/2022051015/556a77dfd8b42a7c758b48da/html5/thumbnails/370.jpg)
その他付録簡単な実装案が書かれている要するにN番目の要素に到達するまで線形再帰する
template <unsigned N, typename T, typename ...R>auto value_at(T&&, R&&... r) -> decltype(auto) { return value_at<N - 1, R...>(std::forward<R>(r)...);}
template auto value_at(T&& t, R&&...) -> decltype(auto) { return std::forward<T>(t);}
![Page 371: Template Meta Programming入門から応用まで](https://reader033.vdocuments.mx/reader033/viewer/2022051015/556a77dfd8b42a7c758b48da/html5/thumbnails/371.jpg)
その他付録
対数オーダーで実装可能なのでAuthorに実装の改良を提案する意見を送付した
![Page 372: Template Meta Programming入門から応用まで](https://reader033.vdocuments.mx/reader033/viewer/2022051015/556a77dfd8b42a7c758b48da/html5/thumbnails/372.jpg)
その他付録
対数オーダーでの要素アクセスの実装
![Page 373: Template Meta Programming入門から応用まで](https://reader033.vdocuments.mx/reader033/viewer/2022051015/556a77dfd8b42a7c758b48da/html5/thumbnails/373.jpg)
その他付録
次のようなメタ関数を用意するtemplate<std::size_t N, class T = void>using make_type_sequence = typename make_type_sequence_impl<N, T>::type;
// make N-1 Ts type_sequence<T, T, ..., T> O(log2(N))
implでindex_rangeのように型列を対数オーダーで生成する
![Page 374: Template Meta Programming入門から応用まで](https://reader033.vdocuments.mx/reader033/viewer/2022051015/556a77dfd8b42a7c758b48da/html5/thumbnails/374.jpg)
その他付録
次のようなメタ関数を用意するtemplate<class T>struct type_wrapper{ using type = T;}; ただ型を保持するだけの型
![Page 375: Template Meta Programming入門から応用まで](https://reader033.vdocuments.mx/reader033/viewer/2022051015/556a77dfd8b42a7c758b48da/html5/thumbnails/375.jpg)
その他付録template<class T, std::size_t N>struct type_at{private: template<template<class...> class Type, class... Args> static auto impl(type_wrapper<Type<Args...>>) -> typename type_at_impl<N, type_wrapper<Args>...>::type; public: using type = typename decltype(impl(type_wrapper<T>()))::type; }; 型リストを持つコンテナ型TとインデックスNを受け取る
![Page 376: Template Meta Programming入門から応用まで](https://reader033.vdocuments.mx/reader033/viewer/2022051015/556a77dfd8b42a7c758b48da/html5/thumbnails/376.jpg)
その他付録template<class T, std::size_t N>struct type_at{private: template<template<class...> class Type, class... Args> static auto impl(type_wrapper<Type<Args...>>) -> typename type_at_impl<N, type_wrapper<Args>...>::type; public: using type = typename decltype(impl(type_wrapper<T>()))::type;}; type_wrapperに包んでTをimplに渡す
![Page 377: Template Meta Programming入門から応用まで](https://reader033.vdocuments.mx/reader033/viewer/2022051015/556a77dfd8b42a7c758b48da/html5/thumbnails/377.jpg)
その他付録
type_wrapperの役割・インスタンス化出来ない型も処理出来るようにする
![Page 378: Template Meta Programming入門から応用まで](https://reader033.vdocuments.mx/reader033/viewer/2022051015/556a77dfd8b42a7c758b48da/html5/thumbnails/378.jpg)
その他付録type_wrapperの役割
using type = typename decltype(impl(type_wrapper<T>()))::type;
例えばTがtemplate<class...> struct list; のようなインスタンス化不可能な型の場合
impl(list())はインスタンス化出来ずエラーになるがimpl(type_wrapper<T>())ならばインスタンス化出来て渡せる
![Page 379: Template Meta Programming入門から応用まで](https://reader033.vdocuments.mx/reader033/viewer/2022051015/556a77dfd8b42a7c758b48da/html5/thumbnails/379.jpg)
その他付録
type_wrapperの役割・トップレベルのcv修飾を保持する
![Page 380: Template Meta Programming入門から応用まで](https://reader033.vdocuments.mx/reader033/viewer/2022051015/556a77dfd8b42a7c758b48da/html5/thumbnails/380.jpg)
その他付録
type_wrapperの役割
impl(type_wrapper<T>())ならば値渡しの際もArgument
Deductionにおいて、Tのcv修飾情報が失われずに済む
![Page 381: Template Meta Programming入門から応用まで](https://reader033.vdocuments.mx/reader033/viewer/2022051015/556a77dfd8b42a7c758b48da/html5/thumbnails/381.jpg)
その他付録template<class T, std::size_t N>struct type_at{private: template<template<class...> class Type, class... Args> static auto impl(type_wrapper<Type<Args...>>) -> typename type_at_impl<N, type_wrapper<Args>...>::type; public: using type = typename decltype(impl(type_wrapper<T>()))::type;}; template template parameterを使えばテンプレートクラスの持つ型リストを抽出する事が出来る
![Page 382: Template Meta Programming入門から応用まで](https://reader033.vdocuments.mx/reader033/viewer/2022051015/556a77dfd8b42a7c758b48da/html5/thumbnails/382.jpg)
その他付録template<class T, std::size_t N>struct type_at{private: template<template<class...> class Type, class... Args> static auto impl(type_wrapper<Type<Args...>>) -> typename type_at_impl<N, type_wrapper<Args>...>::type; public: using type = typename decltype(impl(type_wrapper<T>()))::type;}; auto f() -> の形式の戻り値指定を使えば戻り値型部分でもparameter packを展開したり出来る
![Page 383: Template Meta Programming入門から応用まで](https://reader033.vdocuments.mx/reader033/viewer/2022051015/556a77dfd8b42a7c758b48da/html5/thumbnails/383.jpg)
その他付録template<class T, std::size_t N>struct type_at{private: template<template<class...> class Type, class... Args> static auto impl(type_wrapper<Type<Args...>>) -> typename type_at_impl<N, type_wrapper<Args>...>::type; public: using type = typename decltype(impl(type_wrapper<T>()))::type;}; decltypeされる為だけに存在している関数であれば、関数定義は必要ない
![Page 384: Template Meta Programming入門から応用まで](https://reader033.vdocuments.mx/reader033/viewer/2022051015/556a77dfd8b42a7c758b48da/html5/thumbnails/384.jpg)
その他付録template<class T, std::size_t N>struct type_at{private: template<template<class...> class Type, class... Args> static auto impl(type_wrapper<Type<Args...>>) -> typename type_at_impl<N, type_wrapper<Args>...>::type; public: using type = typename decltype(impl(type_wrapper<T>()))::type;}; またコンパイル時でもdecltypeするだけであればconstexpr修飾は必要無い
![Page 385: Template Meta Programming入門から応用まで](https://reader033.vdocuments.mx/reader033/viewer/2022051015/556a77dfd8b42a7c758b48da/html5/thumbnails/385.jpg)
その他付録
むしろconstexpr修飾された関数は暗黙にinline修飾される上inline修飾された関数の定義がない場合clang等は警告を出すのでconstexpr修飾はしないべき
![Page 386: Template Meta Programming入門から応用まで](https://reader033.vdocuments.mx/reader033/viewer/2022051015/556a77dfd8b42a7c758b48da/html5/thumbnails/386.jpg)
その他付録template<class T, std::size_t N>struct type_at{private: template<template<class...> class Type, class... Args> static auto impl(type_wrapper<Type<Args...>>) -> typename type_at_impl<N, type_wrapper<Args>...>::type; public: using type = typename decltype(impl(type_wrapper<T>()))::type;}; 更にメタ関数を呼び出す
![Page 387: Template Meta Programming入門から応用まで](https://reader033.vdocuments.mx/reader033/viewer/2022051015/556a77dfd8b42a7c758b48da/html5/thumbnails/387.jpg)
その他付録template<std::size_t N, class... Types>struct type_at_impl{ using type = decltype(type_at_impl_impl< make_type_sequence<(N)> >::eval(static_cast< Types* >(nullptr)...) );};
type_sequence<void, void, void, ..., void>とN-1個のvoidを持つ型を対数オーダーで生成してテンプレートパラメータとして次の処理関数に渡す
![Page 388: Template Meta Programming入門から応用まで](https://reader033.vdocuments.mx/reader033/viewer/2022051015/556a77dfd8b42a7c758b48da/html5/thumbnails/388.jpg)
その他付録template<std::size_t N, class... Types>struct type_at_impl{ using type = decltype(type_at_impl_impl< make_type_sequence<(N)> >::eval(static_cast< Types* >(nullptr)...) );};
nullptrを受け取ってきた型リストの型のポインタにキャストしながら展開して次の処理関数に引数として渡す
![Page 389: Template Meta Programming入門から応用まで](https://reader033.vdocuments.mx/reader033/viewer/2022051015/556a77dfd8b42a7c758b48da/html5/thumbnails/389.jpg)
その他付録template<std::size_t N, class... Types>struct type_at_impl{ using type = decltype(type_at_impl_impl< make_type_sequence<(N)> >::eval(static_cast< Types* >(nullptr)...) );};
Typesはtype_wrapper<T>形式の型が入ったパラメータパックなのでその要素は必ずポインタにキャスト出来る
![Page 390: Template Meta Programming入門から応用まで](https://reader033.vdocuments.mx/reader033/viewer/2022051015/556a77dfd8b42a7c758b48da/html5/thumbnails/390.jpg)
その他付録template<std::size_t N, class... Types>struct type_at_impl{ using type = decltype(type_at_impl_impl< make_type_sequence<(N)> >::eval(static_cast< Types* >(nullptr)...) );};
更に実装の無い関数を呼び、decltypeを行う
![Page 391: Template Meta Programming入門から応用まで](https://reader033.vdocuments.mx/reader033/viewer/2022051015/556a77dfd8b42a7c758b48da/html5/thumbnails/391.jpg)
その他付録
template<class... Types>struct type_at_impl_impl<type_sequence<Types...>>{ template<class T> static T eval(Types*..., T*, ...);};
evalはテンプレートパラメータと関数引数の両方を受け取るdecltypeされる事が目的の実装の無い関数
![Page 392: Template Meta Programming入門から応用まで](https://reader033.vdocuments.mx/reader033/viewer/2022051015/556a77dfd8b42a7c758b48da/html5/thumbnails/392.jpg)
その他付録
template<class... Types>struct type_at_impl_impl<type_sequence<Types...>>{ template<class T> static T eval(Types*..., T*, ...);};
TypesはN-1個のvoid型だからstatic_cast<Types*>(nullptr)...としてevalに渡された引数は手前からN-1個までのものはvoid*
という扱いで受け取られる(type erasureが働く)
![Page 393: Template Meta Programming入門から応用まで](https://reader033.vdocuments.mx/reader033/viewer/2022051015/556a77dfd8b42a7c758b48da/html5/thumbnails/393.jpg)
その他付録template<class... Types>struct type_at_impl_impl<type_sequence<Types...>>{ template<class T> static T eval(Types*..., T*, ...);};
Tはtype_wrapper<元のコンテナの型リストのN番目の型>に推論されるtype_wrapperに包まれているのでN番目の型のcv修飾情報は欠落しない
![Page 394: Template Meta Programming入門から応用まで](https://reader033.vdocuments.mx/reader033/viewer/2022051015/556a77dfd8b42a7c758b48da/html5/thumbnails/394.jpg)
その他付録
template<class... Types>struct type_at_impl_impl<type_sequence<Types...>>{ template<class T> static T eval(Types*..., T*, ...);};
残りの余分な引数はellipsisに受け取られるので結果として関数の戻り値型をTにすればdecltypeされた時にTを得る
![Page 395: Template Meta Programming入門から応用まで](https://reader033.vdocuments.mx/reader033/viewer/2022051015/556a77dfd8b42a7c758b48da/html5/thumbnails/395.jpg)
その他付録template<class T, std::size_t N>struct type_at{private: template<template<class...> class Type, class... Args> static auto impl(type_wrapper<Type<Args...>>) -> typename type_at_impl<N, type_wrapper<Args>...>::type; public: using type = typename decltype(impl(type_wrapper<T>()))::type;}; 最終的に::typeでtype_wrapper<元のコンテナの型リストのN
番目の型>の中身である、元のコンテナの型リストのN番目の型が得られる
![Page 396: Template Meta Programming入門から応用まで](https://reader033.vdocuments.mx/reader033/viewer/2022051015/556a77dfd8b42a7c758b48da/html5/thumbnails/396.jpg)
その他付録
補足decltype(expression)::typeはwell-formed
![Page 397: Template Meta Programming入門から応用まで](https://reader033.vdocuments.mx/reader033/viewer/2022051015/556a77dfd8b42a7c758b48da/html5/thumbnails/397.jpg)
その他付録
この手法はNが大きい場合は有効であるが、Nが小さい場合は複雑な実装のメタ関数より線形実装の方が良い場合もある
![Page 398: Template Meta Programming入門から応用まで](https://reader033.vdocuments.mx/reader033/viewer/2022051015/556a77dfd8b42a7c758b48da/html5/thumbnails/398.jpg)
その他付録実際type_atではNが小さい場合が多そうなので悩ましいという話になっている
が、とりあえず次のrevisionでこのような問題についても取り上げて貰える予定である
標準化による結果としてコンパイラマジックによるO(1)の実現というのもあり得るだろうがやはりオーダー自体は重要である
![Page 399: Template Meta Programming入門から応用まで](https://reader033.vdocuments.mx/reader033/viewer/2022051015/556a77dfd8b42a7c758b48da/html5/thumbnails/399.jpg)
その他付録
この方法は同様にしてint,int,int...などのパラメータパック生成とconstexpr関数の組み合わせでvalue_atの実装にも適用出来る(つまりvalue_atも対数オーダー実装が可能)
![Page 400: Template Meta Programming入門から応用まで](https://reader033.vdocuments.mx/reader033/viewer/2022051015/556a77dfd8b42a7c758b48da/html5/thumbnails/400.jpg)
その他付録
実装は
怜-toki-などを見て欲しいhttps://github.com/fimbul/toki
![Page 401: Template Meta Programming入門から応用まで](https://reader033.vdocuments.mx/reader033/viewer/2022051015/556a77dfd8b42a7c758b48da/html5/thumbnails/401.jpg)
おしながき
1. Templateの基本確認2. Template Meta Programmingとは3. Template Meta Programming入門4. Template Meta Programming応用5. その他付録6. まとめ7. 質疑応答
![Page 402: Template Meta Programming入門から応用まで](https://reader033.vdocuments.mx/reader033/viewer/2022051015/556a77dfd8b42a7c758b48da/html5/thumbnails/402.jpg)
今回、コンパイル時に行われるメタプログラミングのポテンシャル、型を扱うプログラミングというもののイメージ
Template Meta Programmingの有用性について少しでも伝わっていれば嬉しいです
まとめ
![Page 403: Template Meta Programming入門から応用まで](https://reader033.vdocuments.mx/reader033/viewer/2022051015/556a77dfd8b42a7c758b48da/html5/thumbnails/403.jpg)
Template Meta Programmingのメリット・型を扱うプログラミングを行える・型検査でバグを実行前の段階で検出する・コンパイル時計算(実行時の処理を減らす)
・工夫でパフォーマンス向上(ET、遅延評価)
など
まとめ
![Page 404: Template Meta Programming入門から応用まで](https://reader033.vdocuments.mx/reader033/viewer/2022051015/556a77dfd8b42a7c758b48da/html5/thumbnails/404.jpg)
Template Meta Programmingのデメリット・酷使すればコンパイル時間が長くなる・実装に実行時とは異なる技術知識が必要・不慣れだとデバッグがつらい(特にgcc)
(膨大なコンパイルエラーメッセージ)
・半分実装して途中経過を見るみたいな 事が難しいので脳内コンパイルも必要など
まとめ
![Page 405: Template Meta Programming入門から応用まで](https://reader033.vdocuments.mx/reader033/viewer/2022051015/556a77dfd8b42a7c758b48da/html5/thumbnails/405.jpg)
デバッグ方法・static_assert
・実行時に結果を標準出力・実態のない型をインスタンス化する (エラーメッセージで型を見る)
・mpl::print(必ずしも上手くはいかない)
など
まとめ
![Page 406: Template Meta Programming入門から応用まで](https://reader033.vdocuments.mx/reader033/viewer/2022051015/556a77dfd8b42a7c758b48da/html5/thumbnails/406.jpg)
スライドの内容はTemplate Meta Programming
の世界のたかだか氷山の一角に過ぎません
まとめ
![Page 407: Template Meta Programming入門から応用まで](https://reader033.vdocuments.mx/reader033/viewer/2022051015/556a77dfd8b42a7c758b48da/html5/thumbnails/407.jpg)
世の中にはラムダ式(Boost.MPL)やレイトレーシング(Sprout)等もTMP(with constexpr)
での実装例がありますし、Metaparseのような(闇の)ライブラリもあります(コンパイル時haskellコンパイラ的なサムシングなど)
まとめ
![Page 408: Template Meta Programming入門から応用まで](https://reader033.vdocuments.mx/reader033/viewer/2022051015/556a77dfd8b42a7c758b48da/html5/thumbnails/408.jpg)
入門から応用までなどと謳ったものの結局殆ど難しいことはろくに取り上げられず申し訳ないです、簡単な内容だけで結構な量になってしまっていたこともあり正直もっと応用的な内容にまで手が回りませんでした
まとめ
![Page 409: Template Meta Programming入門から応用まで](https://reader033.vdocuments.mx/reader033/viewer/2022051015/556a77dfd8b42a7c758b48da/html5/thumbnails/409.jpg)
その実装だけで本一冊書けてしまう、TMP
の世界で最も有名であろうBoost.MPLのようなライブラリを一切取り上げられなかったのは残念です
まとめ
![Page 410: Template Meta Programming入門から応用まで](https://reader033.vdocuments.mx/reader033/viewer/2022051015/556a77dfd8b42a7c758b48da/html5/thumbnails/410.jpg)
代わりに参考書籍を紹介します
まとめ
![Page 411: Template Meta Programming入門から応用まで](https://reader033.vdocuments.mx/reader033/viewer/2022051015/556a77dfd8b42a7c758b48da/html5/thumbnails/411.jpg)
まとめBoost.MPLの解説書
・主にMPLの実装にまつ わる話など・TMPの汎用テクニック・やや情報は古い (C++03向け)
・邦訳もあるはず
![Page 412: Template Meta Programming入門から応用まで](https://reader033.vdocuments.mx/reader033/viewer/2022051015/556a77dfd8b42a7c758b48da/html5/thumbnails/412.jpg)
まとめ
・Template関連本で本当 によく紹介されてい るので多分良書だと 思います・こちらもC++03向け・すいません自分は まだ読めてません
![Page 413: Template Meta Programming入門から応用まで](https://reader033.vdocuments.mx/reader033/viewer/2022051015/556a77dfd8b42a7c758b48da/html5/thumbnails/413.jpg)
まとめ
TC++PL 4th Edition
・C++11に対応した最新 のTC++PL
・Templateの本というわ けではない
![Page 414: Template Meta Programming入門から応用まで](https://reader033.vdocuments.mx/reader033/viewer/2022051015/556a77dfd8b42a7c758b48da/html5/thumbnails/414.jpg)
スライドの誤り等あれば教えて下さい
まとめ
きっとバグあります…
![Page 415: Template Meta Programming入門から応用まで](https://reader033.vdocuments.mx/reader033/viewer/2022051015/556a77dfd8b42a7c758b48da/html5/thumbnails/415.jpg)
ご清聴ありがとうございました
時間がおしていなければ質疑応答に移ります(おしてたら後で個人的にお願いします)
まとめ
![Page 416: Template Meta Programming入門から応用まで](https://reader033.vdocuments.mx/reader033/viewer/2022051015/556a77dfd8b42a7c758b48da/html5/thumbnails/416.jpg)
おしながき
1. Templateの基本確認2. Template Meta Programmingとは3. Template Meta Programming入門4. Template Meta Programming応用5. その他付録6. まとめ7. 質疑応答
![Page 417: Template Meta Programming入門から応用まで](https://reader033.vdocuments.mx/reader033/viewer/2022051015/556a77dfd8b42a7c758b48da/html5/thumbnails/417.jpg)
ありがとうございました
終わり