类型函数
类型函数是这样一个函数:它接受至少一个类型参数或至少生成一个类型结果。如sizeof(T)是一个内置类型函数,它返回给定类型参数T的对象大小。一个类型函数可以接受多个参数,返回多个结果值。例如:
template<
typename T,
int N>
struct Array_type {
using type = T;
static const int dim = N;
};
using Array = Array_type<
int,
3>;
Arrary::type x;
constexpr int s = Array::dim;
返回指定大小的整数类型:
template<
int N>
struct Integer {
using Error =
void;
using type = Select<N, Error,
signed char,
short, Error, Error, Error,
long>;
};
typename Integer<
4>::type i4 =
8;
typename Integer<
1>::type i1 =
9;
在栈中为小对象分配内存,在自由存储空间中为大对象分配内存:
constexpr int on_stack_max =
sizeof(
std::
string);
template<
typename T>
struct Obj_holder {
using type =
typename std::conditional<(
sizeof(T) <= on_statck_max),
Scoped<T>,
On_heap<T>
>::type;
}
void f()
{
typename Obj_holder<
double>::type v1;
typename Obj_holder<
array<double, 200>>::type v2;
}
类型别名
template<
typename C,
typename T,
typename F>
using Conditional =
typename std::conditioanl<C, T, F>::type;
也有不使用别名的情况:当仅有一种候选可能是合法类型是,我们不应使用别名。
conditional<is_integral<T>::value, make_unsigned<T>, Error<T>>::type
类型谓词
template<
typename T>
void copy(T* p,
const T* q,
int n)
{
if (is_pod<T>())
}
选择函数
struct X {
void operator()(
int x) {
cout <<
"X" << x <<
"!" }
};
struct Y {
void operator()(
int y) {
cout <<
"Y" << y <<
"" }
};
void f()
{
Conditional<(
sizeof(
int) >
4), X, Y> {} (
7);
using Z = Conditioanl<(Is_polymorphic<X>()), X, Y>;
Z zz;
zz(
7);
}
萃取
template<
typename Iterator>
struct iterator_traits {
using difference_type =
typename Iterator::difference_type;
using value_type =
typename Iterator::value_type;
using pointer =
typename Iterator::pointer;
using reference =
typename Iterator::reference;
using iterator_category =
typename Iterator::iterator_category;
}
template<
typename Iter>
Iter search(Iter p, Iter q,
typename iterator_traits<Iter>::value_type val)
{
typename iterator_traits<Iter>::difference_type m = q - p;
}
控制结构
选择
在两个类型中选择
template<
bool C,
typename T,
typename F>
struct conditional {
using type = T;
};
template<
typename T,
typename F>
struct conditional<
false, T, F> {
using type = F;
};
在多个类型中选择
class Nil {};
template<
int l,
typename T1 = Nil,
typename T2 = Nil,
typename T3 = Nil,
typename T4 = Nil>
struct select;
template<
int l,
typename T1 = Nil,
typename T2 = Nil,
typename T3 = Nil,
typename T4 = Nil>
using Select =
typename select<l, T1, T3, T4>::type;
template<
int l,
typename T1 = Nil,
typename T2 = Nil,
typename T3 = Nil,
typename T4 = Nil>
struct select<
0, T1, T2, T3, T4> {
using type = T1; };
template<
int l,
typename T1 = Nil,
typename T2 = Nil,
typename T3 = Nil,
typename T4 = Nil>
struct select<
1, T1, T2, T3, T4> {
using type = T2; };
template<
int l,
typename T1 = Nil,
typename T2 = Nil,
typename T3 = Nil,
typename T4 = Nil>
struct select<
2, T1, T2, T3, T4> {
using type = T3; };
template<
int l,
typename T1 = Nil,
typename T2 = Nil,
typename T3 = Nil,
typename T4 = Nil>
struct select<, T1, T2, T3, T4> {
using type = T4; };
Select<
5,
int,
double,
char> x;
迭代和递归
template<
int N>
constexpr int fac()
{
return N*fac<N -
1>();
}
template<>
constexpr int fac<
1>()
{
return 1;
}
constexpr int x5 = fac<
5>();
使用类的递归
template<
int N>
struct Fac {
static const int value = N * Fac<N -
1>::value;
};
tempalte<>
struct Fac<
1> {
static const int value =
1;
};
constexpr int x7 = Fac<
7>::value;
条件定义:Enable_if
使用Enable_if
template<
typename T>
class vector<T>
public:
vector(size_t n,
const T& val);
template<
typename Iter,
typename = Enable_if<Input_iterator<Iter>(),Iter>>
vector(Iter b, Iter e);
};
template<
typename T>
class vector<T>
public:
vector(size_t n,
const T& val);
template<
typename Iter>
vector(Enable_if<Input_iterator<Iter>(),Iter>> b, Iter e);
};
实现Enable_if
Enable_if的实现相当简单,如下
template<
bool B,
typename T =
void>
struct std::enable_if {
typedef T type;
};
template<typeanme T>
struct std::enable_if<
false, T> {};
template<
bool B,
typename T =
void>
using Enable_if =
typename std::enable_if<B, T>::type;
Enable_if例子
检查X类型对象x能否调用f(x)
struct substitution_failure {};
template<
typename T>
struct substitution_succeeded :
std::true_type
{};
template<>
struct substitution_succeeded<substitution_failure> :
std::false_type
{};
template<
typename T>
struct has_f
: substitution_succeeded<
typename get_f_result<T>::type>
{};
template<
typename T>
struct get_f_result {
private:
template<
typename X>
static auto check(X
const& x) ->
decltype(f(x));
static substitution_failure check(...);
public:
using type =
decltype(check(
std::
decltype<T>()));
};
国际标准单位例子
Unit
template<
int M,
int K,
int S>
struct Unit {
enum { m = M, kg = K, s = S };
};
using M = Unit<
1,
0,
0>;
using Kg = Unit<
0,
1,
0>;
using S = Unit<
0,
0,
1>;
using MpS = Unit<
1,
0, -
1>;
using MpS = Unit<
1,
0, -
2>;
template<
typename U1,
typename U2>
struct Uplus {
using type = Unit<U1::m + U2::m, U1::kg + U2::kg, U1::s + U2::s>;
};
template<
typename U1, U2>
using Unit_plus =
typename Uplus<U1, U2>::type;
template<
typename U1,
typename U2>
struct Uminus {
using type = Unit<U1::m - U2::m, U1::kg - U2::kg, U1::s - U2::s>;
};
template<
typename U1, U2>
using Unit_minus =
typename Uminus<U1, U2>::type;
Quantity
template<
typename U>
struct Quantity {
double val;
explicit Quantity(
double d) : val{d} {}
};
Quantity<M> x{
10.5};
Quantity<S> y{
2};
template<
typename U>
Quantity<U>
operator+(Quantity<U> x, Quantity<U> y)
{
return Quantity<U> {x.val + y.val};
}
template<
typename U>
Quantity<U>
operator-(Quantity<U> x, Quantity<U> y)
{
return Quantity<U> {x.val - y.val};
}
template<
typename U1,
typename U2>
Quantity<Unit_plus<U1, U2>>
operator*(Quantity<U1> x, Quantity<U2> y)
{
return Quantity<Unit_plus<U1, U2>> {x.val * y.val};
}
template<
typename U1,
typename U2>
Quantity<Unit_minus<U1, U2>>
operator/(Quantity<U1> x, Quantity<U2> y)
{
return Quantity<Unit_minus<U1, U2>> {x.val / y.val};
}
Unit字面值常量
constexpr Quantity<M>
operator"" _m(
double d) {
return Quantity<M>{d}; }
constexpr Quantity<Kg>
operator"" _kg(
double d) {
return Quantity<Kg>{d}; }
constexpr Quantity<S>
operator"" _s(
double d) {
return Quantity<S>{d}; }
auto distance =
10_m;
auto time =
20_s;
auto speed = distance / time;