模板元编程——《C++程序设计语言(第四版)》第28章 元编程 笔记

xiaoxiao2021-02-28  7

类型函数

类型函数是这样一个函数:它接受至少一个类型参数或至少生成一个类型结果。如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;
转载请注明原文地址: https://www.6miu.com/read-850128.html

最新回复(0)