栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > C/C++/C#

C++Primer 16.1定义模板 习题总结

C/C++/C# 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

C++Primer 16.1定义模板 习题总结

目录

16.1.1 函数模板

练习16.4 模拟实现find标准库函数

练习16.5 print函数,打印任意元素类型,任意大小的数组。

练习16.6 模拟接收一个数组实参的begin end标准库函数的实现。

16.1.2 类模板 

Blob 类模板和BlobPtr类模板实现

练习16.14 Screen类模板,用非类型模板参数定义Screen的高和宽

16.1.3 模板参数 

 默认模板实参: compare函数的进一步定义。

 练习 16.19 16.20

16.1.4 成员模板

练习16.21  DebugDelete类实现,普通类的成员模板。 

 16.1.5 控制实例化

16.1.6  效率与灵活性

练习16.28


16.1.1 函数模板

template   // 其实就是代表一个类型而已,也没啥。
int compare(const T &v1, const T &v2){
    if(v1 < v2) return -1;
    if(v2 < v1) return 1;
    return 0;
}

模板实现compare函数,用于任意两种相同类型的比较,前提是,此类型支持<运算符。

练习16.4 模拟实现find标准库函数
template 
T1 my_find(const T1& beg,const T1& end,const T2& value){
    for(auto i = beg; i != end; ++i){
        if(*i == value)
            return i;
    }
    return end;
}

练习16.5 print函数,打印任意元素类型,任意大小的数组。
template  // sz是unsigned类型常量。
void print(const T (&arr)[sz]){
    for(int i = 0; i != sz; ++i){
        cout<

这里用到了非类型模板参数,其中的unsigned int sz就是一个非类型模板参数,可用于模板中需要常量的地方,根据传来的函数实参进行推断此非类型模板参数的模板实参。比如 第一个print中sz = 5,第二个print中sz = 3

练习16.6 模拟接收一个数组实参的begin end标准库函数的实现。
template 
T* my_begin(T (&arr)[sz]){
    return &arr[0];
}

template 
T* my_end(T (&arr)[sz]){
    return &arr[0] + sz;
}

template 
const T* my_cbegin(const T (&arr)[sz]){
    const T* ret = &arr[0];
    return ret;
}

template 
const T* my_cend(const T (&arr)[sz]){
    const T* ret = &arr[0] + sz;
    return ret;
}

16.1.2 类模板 

Blob 类模板和BlobPtr类模板实现
template  class BlobPtr;
template  class Blob;
template 
    bool operator==(const Blob&, const Blob&);

template 
class Blob{
    friend class BlobPtr;
    friend bool operator== (const Blob&, const Blob&);
public:
    using size_type = typename vector::size_type;
    template  Blob(It t1, It t2);
//    : data(make_shared>(t1,t2)) {}
    Blob(): data(make_shared>()) {}
    Blob(initializer_list il):data(make_shared>(il)) {}
    size_type size()const { return data->size(); }
    bool empty()const { return data->empty(); }
    void push_back(const T& ele) { data->push_back(ele); }
    void push_back(T &&ele) { data->push_back(std::move(ele)); }
    void pop_back();
    T& back();
    const T& back()const;
    T& operator[](size_type i);
    const T& operator[](size_type i)const;
private:
    shared_ptr> data;
    void check(size_type i, const string& msg)const;
};
template  template  Blob::Blob(It t1, It t2):data(make_shared>(t1,t2)) {}
template  void Blob::check(size_type i, const string& msg)const{
    if(i>=data->size())
        throw out_of_range(msg);
}

template  void Blob::pop_back(){
    check(0,"pop_back on empty Blob");
    data->pop_back();
}

template 
T& Blob::back(){
    check(0,"back on empty Blob");
    return data->back();
}

template 
const T& Blob::back()const{
    check(0,"beck on empty Blob");
    return data->back();
}

template 
T& Blob::operator[](size_type i){
    check(i,"subscript out of range");
    return (*data)[i];
}

template 
const T& Blob::operator[](size_type i)const{
    check(i,"subscript out of range");
    return (*data)[i];
}

template 
class BlobPtr
{
public:
    BlobPtr(): curr(0) {}
    BlobPtr(Blob& a, size_t sz = 0): wptr(a.data), curr(sz) {}  // 仅一个Blob对象作为参数,curr默认为0;
    T& operator*() const{
        auto p = check(curr, "dereference past end");
        return (*p)[curr];
    }
    // prefix
    BlobPtr& operator++();
    BlobPtr& operator--();
    // postfix
    BlobPtr operator ++(int);
    BlobPtr operator --(int);
private:
    // returns a shared_ptr to the vector if the check succeeds;
    shared_ptr> check(size_t, const string& msg)const;
    weak_ptr> wptr;
    size_t curr;
};

template 
shared_ptr> BlobPtr::check(size_t index, const string& msg)const{
    auto p = wptr.lock();
    if (p) {
        if (p->size() > index) {
            return p;
        } else {
            throw std::out_of_range(msg);
        }
    } else {
        throw "unbind BlobPtr";
    }
}

// prefix ++
template  BlobPtr& BlobPtr::operator++(){
    check(curr, "increment past end of StrBlob");
    ++curr;
    return *this;
}
template  BlobPtr& BlobPtr::operator--(){
    --curr;
    check(-1, "decrease index pass the beg");
    return *this;
}

template  BlobPtr BlobPtr::operator++(int){
    BlobPtr ret = *this;
    ++*this;  // 利用前置加加检验递增是否合法
    return ret;
}

template  BlobPtr BlobPtr::operator--(int){
    BlobPtr ret = *this;
    --*this;
    return ret;
}

Blob类模板,就是很简单的一个类模板的练习,模拟vector,根据模板实参确定保存的元素类型。剩余的就是一些定义,声明的规则了。还有,比如使用类模板的类型成员,需要声明typename,类模板的模板成员,如Blob类的接收两个迭代器参数的构造函数,就是一个函数模板,定义时,类模板的模板参数列表和函数模板的模板参数列表都需要声明。以及BlobPtr类定义时,在参数的作用域范围内,返回值BlobPtr可以省略模板实参,这都是一些小的规则而已。

练习16.14 Screen类模板,用非类型模板参数定义Screen的高和宽
#ifndef C__PRIMER_SCREEN_16_14_H
#define C__PRIMER_SCREEN_16_14_H

#include
#include
using namespace std;
template class Screen; // 声明这个,下面的<<>>声明才可以
template ostream& operator<<(ostream& os, const Screen&);
template istream& operator>>(istream& is, Screen&);
template 
class Screen{
    friend ostream& operator<< (ostream&,const Screen&);
    friend istream& operator>> (istream&,Screen&);
public:
    Screen() : contents(W*H,' ') {}
    Screen(char c):contents(W*H, c) {}
    char get()const { return contents[cursor]; }  // 隐式内联
    inline char get(int, int)const;    // 显式内联
    Screen& clear(char c = bkground);
private:
    static const char bkground = ' ';
public:
    Screen& move(int,int);
    Screen& set(char);
    Screen& set(int,int,char);
    Screen& display(ostream& os)
        { do_display(os); return *this; }
    const Screen& display(ostream& os)const
        { do_display(os); return *this;}
private:
    //实际完成显式的函数
    void do_display(ostream& os)const {os< inline char Screen::get(int r,int c)const{
    return contents[r*W+c];
}
template Screen& Screen::clear(char c){
    contents = string(H*W,c);
    return *this;
}
template  inline Screen& Screen::move(int r,int c){
    cursor = r*W+c;
    return *this;
}

template
Screen& Screen::set(char c){
    contents[cursor] = c;
    return *this;
}
template
Screen& Screen::set(int r,int col,char ch){
    contents[r*W+col] = ch;
    return *this;
}

template ostream& operator<<(ostream& os, const Screen& s){
    os< istream& operator>>(istream& is, Screen& s){
    string t;
    cin >> t;
    s.contents = t.substr(0,H*W);
    return is;
}

#endif //C__PRIMER_SCREEN_16_14_H

 用非类型模板实参确定Screen的高和宽,而不是之前的把高和宽定义为私有数据成员。也是一个练习而已。注意<< >> 运算符重载函数,仍然需要模板,且友元声明时,   

friend ostream& operator<< (ostream&,const Screen&);
friend istream& operator>> (istream&,Screen&);

需要加上。还有类模板的声明,以及函数声明。

16.1.3 模板参数 

 默认模板实参: compare函数的进一步定义。
template < typename T, typename F = less >
int compare(const T& v1, const T& v2, F f = F()){
    if(f(v1,v2))
        return -1;
    if(f(v2,v1))
        return 1;
    return 0;
}

 练习 16.19 16.20
// 16.19
template 
void print(const T& v){
    for(typename T::size_type sz = 0; sz!=v.size();++sz) {
        cout << v[sz] << " ";
    }
}

template 
void print_2(const T& v){
    for(auto i = v.begin(); i != v.end(); ++i){
        cout<<*i<<" ";
    }
    cout< 

 使用类的类型成员

16.1.4 成员模板

练习16.21  DebugDelete类实现,普通类的成员模板。 
// 16.1.4
class DebugDelete
{
public:
    explicit DebugDelete(ostream& o = cerr): os(o) {}
    template  void operator() (T* p)const { cout<<"deleting unique_ptr"< 

 16.1.5 控制实例化

 ........

16.1.6  效率与灵活性

练习16.28  shared_ptr unique_ptr简单实现
// 16.1.6 效率与灵活性   test16_28
template 
class Shared_p{
public:
    Shared_p():p(nullptr), use(nullptr){}
    // shared_p p(new int(1));
    explicit Shared_p(T* pt):p(pt), use(new size_t(1)) {}
    Shared_p(const Shared_p& sp): p(sp.p),use(sp.use){
        if(use) ++*use;
    }
    Shared_p& operator=(const Shared_p& sp);
    ~Shared_p();
    T& operator*() { return *p; }
    T& operator*()const { return *p; }
private:
    T* p;
    size_t* use;
};

template Shared_p& Shared_p::operator=(const Shared_p& rhs){
    if(rhs.use)
        ++*use;
    if(use && --*use == 0) {
        delete p;
        delete use;
    }
    p = rhs.p;
    use = rhs.use;
    return *this;
}

template Shared_p::~Shared_p(){
    if(use && --*use == 0){
        delete use;
        delete p;
    }
}
template 
Shared_p make_shared(Args&&... args){
    return Shared_p(new T(forward(args)...));
}

template 
class UP
{
public:
    UP():p(nullptr){}
    explicit UP(T* pt):p(pt){}
    UP(const UP&) = delete;
    UP& operator=(const UP&)=delete;
    ~UP(){
        if(p)
            delete p;
    }
    T* release(){
        T* ret = p;
        p = nullptr;
        return ret;
    }
    T* reset(T* new_p = nullptr){
        if(p)
            delete p;
        p = new_p;
    }
    T& operator*() { return *p; }
    T* operator*()const { return *p; }
private:
    T* p;
};

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/990988.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号