SlideShare a Scribd company logo
C++14

変数テンプレート

高橋 晶(Akira Takahashi)
faithandbrave@longgate.co.jp
2013/10/26(土) C++14規格レビュー勉強会
はじめに
•

この発表は、C++14のコア言語に導入される予定の
「変数テンプレート(Variable Templates)」に関するレビュー資料です。

•

提案文書:
http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2013/n3651.pdf

•

日本語訳:
http://dl.dropboxusercontent.com/u/1682460/translation/C++14/
n3651_variable_templates.html
概要
•

この提案の狙いは、パラメータ化された定数の定義と使用をシンプルにす
ることである。

•

これは、constexpr変数テンプレート(Variable Templates)の宣言によっ
て許可する。

•

その結果として、よりシンプルなプログラミングルールを覚えやすくす
る。これによって、現在知られている回避策を、より予測可能な慣習と意
味論で置き換える。
変数テンプレートの使い方
•

数学の定数であるπを、浮動小数点数型の精度を指定して直接的に表現し
たい。

template <typename T>
constexpr T pi = T(3.1415926535897932385);
変数テンプレートの使い方
•

そしてこれをジェネリックな関数内で使用したい。たとえば、与えられた
半径から円の面積を計算する。

template <typename T>
T area_of_circle_with_radius(T r)
{
return pi<T> * r * r;
}
変数テンプレートの使い方
•

変数テンプレートの型は、組み込み型に制限されない。ユーザー定義型も
使用可能だ。

•

たとえば、ここにパウリ行列(Pauli matrices)の基本的な定義がある(これ
は量子力学で使用する)。
template <typename T>
constexpr pauli<T> sigma1 = { { 0, 1 }, { 1, 0 } };
template <typename T>
constexpr pauli<T> sigma2 = { { 0, -1i }, { 1i, 0 } };
template <typename T>
constexpr pauli<T> sigma3 = { { 1, 0 }, { -1, 0 } };

•

pauli<T>は2x2行列のcomplex<T>型として定義される。
これまでの回避策
•

変数テンプレート宣言がないC++11までは、以下の2つの回避策がとられ
ていた。

•

クラステンプレートのconstexpr静的データメンバ

•

constexpr関数テンプレートによって返される結果値
回避策1. constexpr静的データメンバ

•

標準のstd::numeric_limitsクラスで、この回避策がとられている。
template <typename T>
struct numeric_limits {
static constexpr bool is_modulo = ...;
};
// ...
template <typename T>
constexpr bool numeric_limits<T>::is_modulo;
回避策1. constexpr静的データメンバ
静的データメンバの主な問題:

•

それらは「重複する」宣言を要求する: その定数がodr-usedである場合、
クラステンプレートの内側に一度、クラステンプレートの外側に一度、
「本物の(real)」定義を提供する。

•

プログラマは、同じ宣言を2回宣言する必要性に怒り、混乱する。
対照的に、「普通の(ordinary)」定数宣言では重複した宣言は必要ない。

つまり何を言ってるのか?
回避策1. constexpr静的データメンバ
template <class T>
struct X {
static constexpr bool is_modulo = false;
};
/*
template <class T>
constexpr bool X<T>::is_modulo;
*/
int main()
{
constexpr const bool& x = X<int>::is_modulo; // リンクエラー!
}

•
•
•

宣言しかされていない段階で、is_moduloを「使用」している。
この段階では、is_moduloに実体がないため、ポインタや参照はとれない。
上記コメントアウトを外して、is_moduloを定義しなければならない。
回避策2. constexpr関数テンプレート

•

この回避策をとっているものには、std::numeric_limitsの静的メンバ
関数や、boost::math::constants::pi<T>()関数などがある。

•

こちらの回避策では、静的データメンバが持つ「重複宣言」問題は起こら
ない。

•

この回避策の問題は、データの使用方法(const参照なのか非const参照な
のか、もしくはコピーなのか)を、提供側が事前に選択しなければならな
い、ということ。

•

もしコピーを返す方法が一つだけ用意されていたとして、組み込み型なら
大した問題にはならないが、行列や多倍長演算型の場合に致命的になる。
解決策

constexpr変数テンプレートを使いましょう
具体的な規格の変更内容

•

もともと、構文的にはあらゆる宣言にテンプレートを付けることが可能に
なっている。

•

規格への変更内容は、変数宣言をテンプレートの許可リストに加えるだけ。
特殊化について

•

変数テンプレートは、特殊化、および部分特殊化をサポートする。
所感

•

元々浅い理解だったときは、constexpr関数で十分だと考えていたが、
odr-usedと、使用方法のユーザー側選択の説明で、納得が行った。

•

懸念事項としては、変数テンプレートは可変個変数とかができてしまうは
ずなので、
「テンプレートがいくつインスタンス化されたかの個数と、インスタンス化
された型リストを取得したい」
という要望が出てきそうで怖いと感じた。

•
•

→ でもそれは静的データメンバも同じだった。

現状の機能と動機については、全く問題ないと考える。
可変個変数

•

テンプレートパラメータごとに異なるインスタンスを持つので、同じ変数名
でも別な型と値を持てる。(Clang 3.5になる予定のtrunkで確認)

template<int x>
constexpr char y = 3;
template<>
constexpr double y<42> = 2.5;
int main()
{
constexpr char c = y<17>;
constexpr double d = y<42>;

}

static_assert(c == 3, "");
static_assert(d == 2.5, "");

http://stackoverflow.com/questions/19108345/c1y-c14-variable-template-specialization
標準ライブラリへの採用展望

•

C++14での、Type Traitsのエイリアステンプレート版追加にともない、
同提案者のVicente J. Botet Escribaさんが、値を返すメタ関数の変数テン
プレート版を提案しようとしている(C++14には間に合わないだろう)。

•

RFC: TypeTraits Variables - std-proposals
https://groups.google.com/a/isocpp.org/forum/?
hl=en&fromgroups#!topic/std-proposals/QOYLLJjH98k

template<typename T>
constexpr bool is_reference_c = is_reference<T>::value;
参考文献

•

N3552 Walter Brown. Introducing Object Aliases.
http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2013/n3552.pdf

•

N3615 Gabriel Dos Reis. Constexpr Variable Templates.
http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2013/n3615.pdf

More Related Content

PDF
Executors and schedulers
PDF
C++14 relaxing constraints on constexpr
PDF
C++14 binary literals
PPTX
契約プログラミング
PDF
Riverpodでテストを書こう
PDF
C++0x concept
PDF
C++コンパイラ GCCとClangからのメッセージをお読みください
PDF
テンプレートメタプログラミング as 式
Executors and schedulers
C++14 relaxing constraints on constexpr
C++14 binary literals
契約プログラミング
Riverpodでテストを書こう
C++0x concept
C++コンパイラ GCCとClangからのメッセージをお読みください
テンプレートメタプログラミング as 式

Viewers also liked (12)

PPTX
C++ tips1 #include編
PPTX
ナウなヤングにバカうけのイカしたタグ付き共用体
PPTX
C++ tips4 cv修飾編
PPTX
C++ tips 3 カンマ演算子編
PDF
C++ tips2 インクリメント編
PDF
Learning Template Library Design using Boost.Geomtry
PDF
Boost tour 1_61_0 merge
PDF
C++1z draft
PDF
C++ マルチスレッド 入門
PDF
よいコード、わるいコード
PDF
インフラエンジニアがUnityをやるべきたった一つの理由
PDF
プログラムを高速化する話
C++ tips1 #include編
ナウなヤングにバカうけのイカしたタグ付き共用体
C++ tips4 cv修飾編
C++ tips 3 カンマ演算子編
C++ tips2 インクリメント編
Learning Template Library Design using Boost.Geomtry
Boost tour 1_61_0 merge
C++1z draft
C++ マルチスレッド 入門
よいコード、わるいコード
インフラエンジニアがUnityをやるべきたった一つの理由
プログラムを高速化する話
Ad

Similar to C++14 variable templates (20)

PPTX
C# design note sep 2014
PPTX
C#とJavaの違い
PDF
設計/原理 【クラウドアプリケーションのためのオブジェクト指向分析設計講座 第28回】
PDF
最先端NLP勉強会2017_ACL17
PDF
qmake入門
PDF
Skinny Controllers, Skinny Models
PDF
CMSI計算科学技術特論C (2015) OpenMX とDFT②
PPTX
N3701 concept lite
PPT
「C言語規格&MISRA-C:みんなで楽しいCプログラミング」NGK2013B名古屋合同懇親会2013忘年会昼の部
PDF
【C++BUILDER STARTER チュートリアルシリーズ】シーズン2 C++Builderの部 第2回 ‟変数と型„
PDF
What is template
PPTX
PPTX
わんくま名古屋 #37 (20151114) TDD道場 #25
PDF
PostgreSQL17対応版 EXPLAINオプションについて (第49回PostgreSQLアンカンファレンス@東京 発表資料)
PDF
CMSI計算科学技術特論C (2015) 可読性と性能の両立を目指して
PDF
Scala + Finagleの魅力
PDF
PHP 2大 web フレームワークの徹底比較!
PDF
実装(2) 【クラウドアプリケーションのためのオブジェクト指向分析設計講座 第31回】
PDF
Coderetreat
PDF
設計/コンポーネント設計(2) 【クラウドアプリケーションのためのオブジェクト指向分析設計講座 第21回】
C# design note sep 2014
C#とJavaの違い
設計/原理 【クラウドアプリケーションのためのオブジェクト指向分析設計講座 第28回】
最先端NLP勉強会2017_ACL17
qmake入門
Skinny Controllers, Skinny Models
CMSI計算科学技術特論C (2015) OpenMX とDFT②
N3701 concept lite
「C言語規格&MISRA-C:みんなで楽しいCプログラミング」NGK2013B名古屋合同懇親会2013忘年会昼の部
【C++BUILDER STARTER チュートリアルシリーズ】シーズン2 C++Builderの部 第2回 ‟変数と型„
What is template
わんくま名古屋 #37 (20151114) TDD道場 #25
PostgreSQL17対応版 EXPLAINオプションについて (第49回PostgreSQLアンカンファレンス@東京 発表資料)
CMSI計算科学技術特論C (2015) 可読性と性能の両立を目指して
Scala + Finagleの魅力
PHP 2大 web フレームワークの徹底比較!
実装(2) 【クラウドアプリケーションのためのオブジェクト指向分析設計講座 第31回】
Coderetreat
設計/コンポーネント設計(2) 【クラウドアプリケーションのためのオブジェクト指向分析設計講座 第21回】
Ad

More from Akira Takahashi (20)

PPTX
Cpp20 overview language features
PDF
Cppmix 02
PPTX
Cppmix 01
PDF
Modern C++ Learning
PDF
cpprefjp documentation
PDF
Boost tour 1_61_0
PDF
error handling using expected
PDF
Boost tour 1.60.0 merge
PDF
Boost tour 1.60.0
PDF
Boost container feature
PDF
Boost Tour 1_58_0 merge
PDF
Boost Tour 1_58_0
PDF
C++14 solve explicit_default_constructor
PDF
C++14 enum hash
PDF
Multi paradigm design
PDF
Start Concurrent
PDF
Programmer mind
PDF
Boost.Study 14 Opening
PDF
Improvement future api
PDF
Leaning random using Boost Random
Cpp20 overview language features
Cppmix 02
Cppmix 01
Modern C++ Learning
cpprefjp documentation
Boost tour 1_61_0
error handling using expected
Boost tour 1.60.0 merge
Boost tour 1.60.0
Boost container feature
Boost Tour 1_58_0 merge
Boost Tour 1_58_0
C++14 solve explicit_default_constructor
C++14 enum hash
Multi paradigm design
Start Concurrent
Programmer mind
Boost.Study 14 Opening
Improvement future api
Leaning random using Boost Random

C++14 variable templates