non-type template-parameter
non-type template-parameterになれる条件(重要)
1.integral or enumeration type(実質整数型)
2. pointer to object or pointer to function
3. lvalue reference to object or lvalue reference to
function
4. pointer to member
5. std::nullptr_t (実質ポインタ型)
(又はこれらにcv修飾子が付いたもの)
のいずれかを満たす型であるとき
non-type template-parameter
例 N3337p305
template<double d> class X; // Error
浮動小数点型は条件に一致しない
template<double* pd> class Y; // OK
pointer to objectなのでOK
template<double& rd> class Z; // OK
lvalue referenceなのでOK
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> {};
84.
Class templates
template<class T1,class T2, int I> class A {}; // unspecialized
template<class T, int I> class A<T, T*, I> {};
このように抽象的なテンプレートパラメータの数を減らし
部分的に具体的要素に置き換えた特殊化を作る事が出来る
85.
Class templates
template<class T1,class T2, int I> class A {}; // unspecialized
template<class T, int I> class A<T, T*, I> {};
部分特殊化されたテンプレートは、条件を満たす場合には
特殊化されていないテンプレートより優先的にマッチする
86.
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において非常に重要
Alias templates
1. Atemplate-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.
118.
Alias templates
2. Whena 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 templateparameters in the type-id of the alias template.
Template Meta Programming入門
template<classT, class U> // different types
struct is_same {
static constexpr auto value = false;
};
template<class T> // same type
struct is_same<T, T> {
static constexpr auto value = true;
};
Template Meta Programming入門
std::conditionalと同じ働きのメタ関数
template<boolB, class T, class F> // true
struct conditional { using type = T; };
template<class T, class F> // false
struct conditional<false, T, F> { using type = F; };
型を返す場合はメンバ型を定義してやる
typename conditional<true, int, char>::type // int
Template Meta Programming応用
条件
・this(非静的メンバ関数の本体に暗黙の変換の結果を含む、クラスメンバアク
セス式の後置式、として表れていない場合)
・リテラルクラスのconstexprコンストラクタとconstexpr関数以外の関数呼び出
し(オーバーロードの解決は普段通り適用される)
・constexpr関数やconstexprコンストラクタの定義の外での未定義動作の
constexpr関数や、未定義動作のconstexprコンストラクタの呼び出し
222.
Template Meta Programming応用
条件
・constantexpressionを生成しないような引数を用いての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ではない
223.
Template Meta Programming応用
条件
・constantexpressionを生成しないような引数による、初期化リストのみからな
るconstexprコンストラクタの呼び出し
例
int x; // not constant
struct A {
constexpr A(bool b) : m(b?42:x) { }
int m;
};
constexpr int v = A(true).m; // OK
constexpr int w = A(false).m; // エラー mの初期化に用いられるxが定数でない
Template Meta Programming応用
decltype
Thetype 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.
233.
Template Meta Programming応用
decltype
ife is an unparenthesized id-expression or an unparenthesized
class member access ...
要するにexpressionが括弧で囲まれていないような
decltype(expression)の形のものの場合
234.
Template Meta Programming応用
例
chara;
decltype(a); // char
int b = 1;
int& c = b;
decltype(c); // int&
const int* d;
decltype(d); // const int*
235.
Template Meta Programming応用
例
structa_type { using type = int; };
a_type a;
decltype(a); // a_type
decltype(a)::type; // int
void f(int);
decltype(f); // void (int)
Template Meta Programming応用
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なども含まれる)
その他付録
記事の例のみ引用する
int i =0 ;
int && f() ;
auto
a1 = i ; // int
decltype(auto) a2 = i ; // int
auto
b1 = (i) ; // int
decltype(auto) b2 = (i) ; // int &
auto
c1 = f() ; // int
decltype(auto) c2 = f() ; // int &&
343.
その他付録
関数の戻り値などに利用出来る
template < typenameT, typename U >
auto g( T const & t, U const & u )
-> decltype( auto ) // decltype( f( t, u ) )と書かなくて済む
{
return f( t, u ) ;
}