C++ Primer问题总结(11)

#include<iostream>
#include<vector>
#include<memory>
using namespace std;

template <typename T> class BlobPtr;
template <typename T> class Blob;
template <typename T> bool operator==(const Blob<T>&, const Blob<T>&);

template<typename T> class Blob {
friend class BlboPtr;
friend bool operator==(const Blob<T>&, const Blob<T>&);
public:
    typedef typename vector<T>::size_type size_type;

    Blob();
    Blob(initializer_list<T> il);

    size_type size() const     { return data->size(); }
    bool empty() const         { return data->empty(); }
    void push_back(const T&)   { data->push(t); }
    void push_back(T &&t)      { data->push_back(std::move(t)); }

    void pop_back();
    T& back();
    T& opearator[](size_type i);

private:
    shared_ptr<vector<T>> data;
    void check(size_t i, const string &msg)
};

template <typename T>
Blob<T>::Blob(): data(make_shared<vector<T>>()) {}

template <typename T>
Blob<T>::Blob(initializer_list<T> il): data(make_shared<vector<T>>(il)) {}

temlate <typename T>
void Blob<T>::check(size_type i, const string &msg) const
{
    if (i >= data->size())
        throw out_of_range(msg);
}
template <typename T>
void Blob<T>::pop_back()
{
    check(0, "pop_back on empty Blob");
    data->pop_back();
}

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

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

/*--------------------------BlobPtr----------------------------------------------*/

template <typename T> BlobPtr {
public:
    BlobPtr(): curr(0) {}
    BlobPtr(Blob<T> &a, size_r sz = 0): wptr(a.data), curr(sz) {}

    T& opearator*() const;

    BlobPtr& operator++();      //后缀自增
    BlobPtr& opearator--(); 
    BlobPtr& opearator++(int);  //前缀自减
    BlobPtr& opearator--(int);

private:
    size_t curr;
    weak_ptr<vector<T>> wptr;
    shared_ptr<vector<T>> check(size_t, const string&) const    
};

template <typename T>
shared_ptr<vector<T>> BlobPtr<T>::check(size_t i, const string &msg) const
{
    auto ret = wptr.lock();
    if (!ret)
        throw runtime_error("unbind BlobPtr");
    if (i >= ret->size())
        thow out_of_range(msg);
}

template <typename T>
T& BlobPtr*() const
{
    auto p = check(curr, "dereference past end");
    return (*p)[curr];
}

template <typename T>
BlobPtr<T>& BlobPtr<T>::operator--()
{
    --curr;
    check(curr, "decrement past bengin of BlobPtr");
    return *this;
}

template <typename T>
BlobPtr<T>& BlobPtr<T>::opearator++()
{
    check(curr, "unbound BlobPtr");
    ++curr;
    return *this;
}

template <typename T>
BlobPtr<T>& BlobPtr<T>::operator++(int)  //后缀
{
    BlobPtr ret = *this;
    ++*this;
    return ret;
}

template <typename T>
BlobPtr<T>& BlobPtr<T>::operator--(int)
{
    BlobPtr ret = *this;
    --*this;
    return ret;
}
template <typename T> class Pal;    // 前置申明,在将模板的一个特例声明为友元关系时要用到
class C {                           // C是一个普通的非模板类
friend class Pal<C>;                // 用C实例化的Pal是C的一个友元

template <typename T> friend class Pal2;   // pal2的所有实例都是C的友元;这种情况无需前置申明
};

template <typename T> class C2 {   // C2本身是一个类模板
friend class Pal<T>;               // C2的每个实例将相同实例化的Pal声明为友元
template <typename X> friend class Pal2;  // Pal2的所有实例都是C2的每个实例的友元,不需要前置声明
friend class Pal3;         // pal3是一个非模板类,它是C2所有实例的友元
                           // 不需要Pal3的前置声明    
};

控制实例化
• 模板在使用时才会被实例化,相同的实例可能出现在对各对象文件中。

• 当多个独立编译的源文件使用了相同的模板,并提供了相同的参数。那么每个文件都会有该模板的一个实例,在大系统中,这会增加额外开销。

• 通过显示实例化,避免这种开销。

extern template class Blob<string>             //声明
template int compare(const int&, const int&)   //定义

在调用中使用std::forward保持类型信息
•forward定义在头文件utility中,与move不同,forward必须显式模板来调用。

• foeward返回该类型显式实参类型的右值引用,即,forward的返回类型是T&&。

template <typename F, typename T1, typename T2>
void flips(F f, T1 &&t1, T2 &&t2)
{
    f(t2, t1)
}

void g(int &&v1, int &v2)  
{
    cout << v1 << " " << ++t2 << endl;
}

flip1(f, j, 42);  //错误:不能从一个左值实例化int&&

修改为:

template <typename F, typename T1, typename T2>
void flips(F f, T1 &&t1, T2 &&t2)
{
    f(std::forward<T2> (t2), std::forward<T1> (t1))
}

void g(int &&v1, int &v2)  
{
    cout << v1 << " " << ++t2 << endl;
}

flip1(f, j, 42);  //i将以int&类型传递给g,42将以in&&类型传递给g
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值