59. 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修飾子が付いたもの)
のいずれかを満たす型であるとき
62. non-type template-parameter
例 N3337 p305
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
83. 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において非常に重要
117. 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.
118. 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 templateparameters in the type-id of the alias template.
189. Template Meta Programming入門
template<class T, 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;
};
196. Template Meta Programming入門
std::conditionalと同じ働きのメタ関数
template<bool B, 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
222. Template Meta Programming応用
条件
・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ではない
223. Template Meta Programming応用
条件
・constant expressionを生成しないような引数による、初期化リストのみからな
る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が定数でない
232. Template Meta Programming応用
decltype
The 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.
233. Template Meta Programming応用
decltype
if e is an unparenthesized id-expression or an unparenthesized
class member access ...
要するにexpressionが括弧で囲まれていないような
decltype(expression)の形のものの場合
234. Template Meta Programming応用
例
char a;
decltype(a); // char
int b = 1;
int& c = b;
decltype(c); // int&
const int* d;
decltype(d); // const int*
235. Template Meta Programming応用
例
struct a_type { using type = int; };
a_type a;
decltype(a); // a_type
decltype(a)::type; // int
void f(int);
decltype(f); // void (int)
239. 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なども含まれる)
342. その他付録
記事の例のみ引用する
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 < typename T, typename U >
auto g( T const & t, U const & u )
-> decltype( auto ) // decltype( f( t, u ) )と書かなくて済む
{
return f( t, u ) ;
}
373. その他付録
次のようなメタ関数を用意する
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のように型列を対数オーダーで生成する