模板基础知识2——《C++程序设计语言(第四版)》第24章 泛型算法 笔记

来源:互联网 发布:朗读配音软件 编辑:程序博客网 时间:2024/06/17 12:57

算法和提升

template<typename Iter, typename Val>Val sum(Iter first, Iter last){    Val s = 0;    while (first != last) {        s = s + *first;        ++first;    }    return s;}struct Node { Node *next; int data; };Node *operator++(Node *p) { return p->next; }int operator*(Node *p) { return p->data; }Node *end(lst) { return nullptr; }void test(Node *lst){    int s = sum<int*>(lst, end(lst));}

调用者提供初值

template<typename Iter, typename Val>Val accumulate(Iter first, Iter last, Val s){    while (first != last) {        s = s + *first;        ++first;    }    return s;}

增加元素的运算操作

template<typename Iter, typename Val, typename Oper>Val accumulate(Iter first, Iter last, Val s, Oper op){    while (first != last) {        s = op(s, *first);        ++first;    }    return s;}double ad[] = {1, 2, 3, 4};double s1 = accumulate(ad, ad + 4, 0.0, std::plus<double>);double s2 = accumulate(ad, ad + 4, 1.0, std::multiply<double>);

概念

概念是指对模板实参类型的特定要求,类似现实生活中的国际工业标准。可用约束简要实现概念。

template<typename C>class String {    static_assert(Ordered<C>(), "String's1 character type is not ordered");};

其中Odered定义如下:

template<typename T>constexpr bool Ordered(){    return Regular<T() && Totally_ordered<T>();}template<typename T>constexpr bool Totally_ordered(){    return Equality_comparable<T>()        && Has_less<T>() && Boolean<Less_result<T>>()        && Has_greater<T>() && Boolean<Greater_result<T>>()        && Has_less_equal<T>() && Boolean<Less_equal_result<T>>()        && Has_greater_equal<T>() && Boolean<Greater_equal_result>();}template<typename T>constexpr bool Equality_comparable(){    return Has_equal<T>() && Boolean<Equal_result<T>>()        && Has_not_equal<T>() && Boolean<Not_equal_result<T>>();}template<typename T>constexpr bool Regular(){    return Semiregular<T>() && Equality_comparable<T>();}template<typename>constexpr bool Semiregular(){    return Destructible<T>()        && Default_constructible<T>()        && Move_constructible<T>()        && Move_assignable<T>()        && Copy_constructible<T>()        && Copy_assignable<T>()}

具体化概念

公理

公理是正确而又无法证明的东西,在模板中,用“公理”表示语义属性,如:

template<typename T>bool Copy_equality(T x) //拷贝构造语义{    return T{x} == x; //副本应与源对象相等}template<typename T>bool Copy_assign_equality(T x, T &y) //赋值语义{    return (y = x, y == x); //赋值结果应与源对象相等}template<typename T>bool Move_effect(T x, T &y) //移动语义{    return (x == y ? T{std::move(x)} == y : true) && can_destroy(y);}template<typename T>bool Move_assign_effect(T x, T &y, T &z) //移动赋值语义{    return (y == z ? (x = std::move(y), x == z) : true) && can_destroy(y);}

多实参概念

template<typename Iter, typename Val>Iter find(Iter b, Iter e, Val x);

对于find,要求Iter的解引用类型与Val类型相容

template<typename A, typename B>constexpr bool Equality_comparable(A a, B b){    return Common<T, U>()        && Totally_ordered<T>()        && Totally_ordered<U>()        && Totally_ordered<Common_type<T, U>>()        && Has_less<T, U>() && Boolean<Less_result<T, U>()        && Has_less<U, T>() && Boolean<Less_result<U, T>()        && Has_greater<T, U>() && Boolean<Greater_result<T, U>()        && Has_greater<U, T>() && Boolean<Greater_result<U, T>()        && Has_less_equal<T, U>() && Boolean<Less_equal_result<T, U>()        && Has_less_equal<U, T>() && Boolean<Less_equal_result<U, T>()        && Has_greater_equal<T, U>() && Boolean<Greater_equal_result<T, U>()        && Has_greater_equal<U, T>() && Boolean<Greater_equal_result<U, T>();};

有了这个谓词,可定义find()如下

template<typename Iter, typename Val>Iter find(Iter b, Iter e, Val x){    static_assert(Input_iterator<Iter>(), "find() requires an input iterator");    static_assert(Equality_comparable<Value_type<Iter>, Val>(),                    "find()'s iterator and value arguments must match");    while (b != e ) {        if (*b == x) return b;        ++b;    }    return b;}

值概念

一个约束检查来检查栈能否容纳一定数量的元素:

constexpr int stack_limit = 2048;template<typename T, int N>constexpr bool Stackable(){    return Regular<T> && sizeof(T) * N <= stack_limit;}template<typename T, int N>struct Buffer {    //...};template<typename T, int N>void fct(){    static_assert(Stackable<T, N>(), "fct() buffer won't fit on stack");    Buffer<T, N> buf;    //...}

模板定义检查

一个约束检查模板确保一个类型提供概念所要求的属性。如果模板实际上使用了比概念所保证的更多的属性,可能得到类型错误,如:

template<typename Iter, typename Val>Iter find(Iter b, Iter e, Val x){    static_assert(Input_iterator<Iter>(), "find(): Iter is not a Forward iterator");    static_assert(Equality_comparable<Value_type<Iter>, Val>(),                    "find(): value type doesn't match iterator");    while (b != e) {        if (*b == x)            return b;        b = b + 1;    }    return b;}void f(list<int> &lst, vector<string> &vs){    auto p = find(lst.begin(), lst.end(), 1209); //错误:list并未提供+    auto q = find(vs.begin(), vs.end(), "Cambridge"); //正确:vector提供了+}
阅读全文
0 0
原创粉丝点击