C++ Primer 学习笔记 第十六章模板与泛型编程

578 定义模板

#include <iostream>
#include <vector>
#include <string>
#include <list>
#include <iterator>
#include <memory>
#include <fstream>
#include <algorithm>
#include <functional>
#include <map>
#include <set>
#include <sstream>
using namespace std;



template <typename T>

int compare(const T &v1, const T &v2){
    if(v1<v2) return -1;
    if(v2<v1) return 1;
    return 0;
}

int main(){
	cout << compare(1, 0) << endl; // 1
	vector<int> vec1{7, 2, 3}, vec2{4, 5, 6};
    cout << compare(vec1, vec2) << endl; // 1


}

580 非类型模板参数

#include <iostream>
#include <vector>
#include <string>
#include <list>
#include <iterator>
#include <memory>
#include <fstream>
#include <algorithm>
#include <functional>
#include <map>
#include <set>
#include <sstream>
using namespace std;



template<unsigned N, unsigned M>
int compare(const char (&p1)[N], const char (&p2)[M]){
    return strcmp(p1, p2);
}


int main(){
    // only compare the first letter
    cout << compare("hi", "mom") << endl; // -1


}

581 编写类型无关的代码

#include <iostream>
#include <vector>
#include <string>
#include <list>
#include <iterator>
#include <memory>
#include <fstream>
#include <algorithm>
#include <functional>
#include <map>
#include <set>
#include <sstream>
using namespace std;


template <typename T> class Blob{
public:
    typedef T value_type;
    typedef typename vector<T>::size_type size_type;
    Blob()=default;
    Blob(initializer_list<T> il){}
    size_type size() const {return data->size();}
    bool empty() const {return data->empty();}
    void push_back(const T &t){data->push_back(t);}
    void pop_back(){}
    T& back(){}
    T& operator[](size_type i){}
private:
    shared_ptr<vector<T>> data;
    void check(size_type i,const string &msg) const{}

};

int main(){
    Blob<int> ia;
    Blob<int> ia2={1, 2, 3, 4};

}

584 实例化模板类

#include <iostream>
#include <vector>
#include <string>
#include <list>
#include <iterator>
#include <memory>
#include <fstream>
#include <algorithm>
#include <functional>
#include <map>
#include <set>
#include <sstream>
using namespace std;


template <typename T> class Blob{
public:
    typedef T value_type;
    typedef typename vector<T>::size_type size_type;
    Blob()=default;
    Blob(initializer_list<T> il){}
    size_type size() const {return data->size();}
    bool empty() const {return data->empty();}
    void push_back(const T &t){data->push_back(t);}
    void pop_back(){}
    T& back(){}
    T& operator[](size_type i){}
private:
    shared_ptr<vector<T>> data;
    void check(size_type i,const string &msg) const{}

};

int main(){
    Blob<int> ia;
    Blob<int> ia2={1, 2, 3, 4};
    
    Blob<string> names;
    Blob<double> prices;
    return 0;

}

586 模板类的成员函数以及构造函数

#include <iostream>
#include <vector>
#include <string>
#include <list>
#include <iterator>
#include <memory>
#include <fstream>
#include <algorithm>
#include <functional>
#include <map>
#include <set>
#include <sstream>
using namespace std;


template <typename T> class Blob{
public:
    typedef T value_type;
    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 &&t){data->push_back(move(t));}
    void pop_back();
    T& back();
    T& operator[](size_type i);
private:
    shared_ptr<vector<T>> data;
    void check(size_type i,const string &msg) const;

};

template <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>
T & Blob<T>::back() {
    check(0, "back on empty Blob");
    return data->back();
}

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

template <typename T> void Blob<T>::pop_back() {
    check(0, "empty blob");
    data->pop_back();
}

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)) {

}


int main(){
    Blob<int> ia;
    Blob<int> ia2={1, 2, 3, 4};

    Blob<string> articles = {"a", "an", "the"};

    Blob<int> squares = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9};
    for (size_t i=0;i!=squares.size();++i){
        squares[i] = i*i;
    }


    return 0;

}

588

#include <iostream>
#include <vector>
#include <string>
#include <list>
#include <iterator>
#include <memory>
#include <fstream>
#include <algorithm>
#include <functional>
#include <map>
#include <set>
#include <sstream>
using namespace std;


template <typename T> class Blob{
public:
    typedef T value_type;
    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 &&t){data->push_back(move(t));}
    void pop_back();
    T& back();
    T& operator[](size_type i);
    shared_ptr<vector<T>> data;
private:
    void check(size_type i,const string &msg) const;

};

template <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>
T & Blob<T>::back() {
    check(0, "back on empty Blob");
    return data->back();
}

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

template <typename T> void Blob<T>::pop_back() {
    check(0, "empty blob");
    data->pop_back();
}

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)) {

}


template <typename T> class BlobPtr{
public:
    BlobPtr():curr(0){}
    BlobPtr(Blob<T> &a, size_t sz=0):wptr(a.data),curr(sz){}
    T& operator*() const{
        auto p = check(curr, "dereference past end");
        return (*p)[curr];
    }

    BlobPtr& operator++(int);
//    or
//    BlobPtr<T>& operator++(int);
    BlobPtr& operator--();
private:
    shared_ptr<vector<T>> check(size_t, string&) const;
    weak_ptr<vector<T>> wptr;
    size_t curr;
};

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


int main(){
    Blob<int> blob{1, 2, 3, 4};
    BlobPtr<int> blob_ptr(blob, 0);
    return 0;

}

589 模板类与友元

#include <iostream>
#include <vector>
#include <string>
#include <list>
#include <iterator>
#include <memory>
#include <fstream>
#include <algorithm>
#include <functional>
#include <map>
#include <set>
#include <sstream>
using namespace std;


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

template <typename T> class Blob{
    friend class BlobPtr<T>;
    friend bool operator==<T>(const Blob<T>&, const Blob<T>&);
public:
    typedef T value_type;
    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 &&t){data->push_back(move(t));}
    void pop_back();
    T& back();
    T& operator[](size_type i);

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

};

template <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>
T & Blob<T>::back() {
    check(0, "back on empty Blob");
    return data->back();
}

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

template <typename T> void Blob<T>::pop_back() {
    check(0, "empty blob");
    data->pop_back();
}

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)) {

}


template <typename T> class BlobPtr{
public:
    BlobPtr():curr(0){}
    BlobPtr(Blob<T> &a, size_t sz=0):wptr(a.data),curr(sz){}
    T& operator*() const{
        auto p = check(curr, "dereference past end");
        return (*p)[curr];
    }

    BlobPtr& operator++(int);
//    or
//    BlobPtr<T>& operator++(int);
    BlobPtr& operator--();
private:
    shared_ptr<vector<T>> check(size_t, string) const;
    weak_ptr<vector<T>> wptr;
    size_t curr;
};

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

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


int main(){
    Blob<int> blob{1, 2, 3, 4};
    BlobPtr<int> blob_ptr(blob, 0);

    cout << *blob_ptr << endl;
    blob_ptr++;
    cout << *blob_ptr << endl;

    return 0;

}

589 通用和特定模板友好关系

#include <iostream>
#include <vector>
#include <string>
#include <list>
#include <iterator>
#include <memory>
#include <fstream>
#include <algorithm>
#include <functional>
#include <map>
#include <set>
#include <sstream>
using namespace std;


template <typename T> class Pal;
class C{
    friend class Pal<C>;
    template<class T> friend class Pal2;
};

template <typename T> class C2{
    friend class Pal<T>;
    template<class X> friend class Pal2;
    friend class Pal3;
};


int main(){
    return 0;

}

590 为模板类起别名

#include <iostream>
#include <vector>
#include <string>
#include <list>
#include <iterator>
#include <memory>
#include <fstream>
#include <algorithm>
#include <functional>
#include <map>
#include <set>
#include <sstream>
using namespace std;


template <typename T> class Blob{
public:
    Blob()=default;

};

typedef Blob<string> StrBlob;

int main(){
    return 0;

}

590 模板类的静态成员

#include <iostream>
#include <vector>
#include <string>
#include <list>
#include <iterator>
#include <memory>
#include <fstream>
#include <algorithm>
#include <functional>
#include <map>
#include <set>
#include <sstream>
using namespace std;


template <typename T> class Foo{
public:
    static size_t count() {return  ctr;}

private:
    static size_t ctr;
};

template <typename T>
size_t Foo<T>::ctr=0;


int main(){

    Foo<int> fi;
    auto ct = Foo<int>::count();
    ct = fi.count();
    // error 哪个模板实例的count?
//    ct = Foo::count();
    return 0;

}

593 模板参数以及模板的声明与定义

#include <iostream>
#include <vector>
#include <string>
#include <list>
#include <iterator>
#include <memory>
#include <fstream>
#include <algorithm>
#include <functional>
#include <map>
#include <set>
#include <sstream>
using namespace std;


template <typename Foo> Foo calc(const Foo& a, const Foo&b){
    
}

template <typename T> int compare(const T&, const T&);
template <typename T> class Blob;

template <typename T> T calc(const T&, const T&);
template <typename U> U calc(const U&, const U&);

template <typename Type>
Type calc2(const Type& a, const Type& b){};


int main(){

    return 0;

}

593 使用类的类型成员

#include <iostream>
#include <vector>
#include <string>
#include <list>
#include <iterator>
#include <memory>
#include <fstream>
#include <algorithm>
#include <functional>
#include <map>
#include <set>
#include <sstream>
using namespace std;


template <typename T>
typename T::value_type top(const T& c){
    if (!c.empty())
        return c.back();
    else
        return typename T::value_type();
}


int main(){

    return 0;

}

594 默认模板实参

#include <iostream>
#include <vector>
#include <string>
#include <list>
#include <iterator>
#include <memory>
#include <fstream>
#include <algorithm>
#include <functional>
#include <map>
#include <set>
#include <sstream>
using namespace std;


template <typename T, typename F=less<T>>
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;
}


int main(){
    bool i = compare(0, 42);
    
    return 0;

}

595

#include <iostream>
#include <vector>
#include <string>
#include <list>
#include <iterator>
#include <memory>
#include <fstream>
#include <algorithm>
#include <functional>
#include <map>
#include <set>
#include <sstream>
using namespace std;


template <class T=int> class Numbers{
public:
    Numbers(T v=0):val(v){}

private:
    T val;
};

int main(){
    Numbers<long double> lots_of_precision;
    Numbers<> average_precision;

}

595 普通的类成员模板

#include <iostream>
#include <vector>
#include <string>
#include <list>
#include <iterator>
#include <memory>
#include <fstream>
#include <algorithm>
#include <functional>
#include <map>
#include <set>
#include <sstream>
using namespace std;


class DebugDelete{
public:
    DebugDelete(ostream &s=cerr):os(s){}

    template<typename T> void operator()(T *p) const{
        os << "deleting unique_ptr" << endl;
        delete p;
    }
private:
    ostream &os;
};
// using as deletor of unique_ptr
unique_ptr<int, DebugDelete> p(new int, DebugDelete());


int main(){
    double *p = new double;
    DebugDelete d;
    d(p);

    int *ip = new int(32);
    DebugDelete()(ip);
}

596 类成员的模板

#include <iostream>
#include <vector>
#include <string>
#include <list>
#include <iterator>
#include <memory>
#include <fstream>
#include <algorithm>
#include <functional>
#include <map>
#include <set>
#include <sstream>
using namespace std;


template <typename T> class Blob{
    template<typename It> Blob(It b, It e);

private:
    shared_ptr<vector<T>> data;
};

template <typename T>
template <typename It>
Blob<T>::Blob(It b, It e):data(make_shared<vector<T>>(b, e)) {}

int main(){

}

597 实例化类成员模板

#include <iostream>
#include <vector>
#include <string>
#include <list>
#include <iterator>
#include <memory>
#include <fstream>
#include <algorithm>
#include <functional>
#include <map>
#include <set>
#include <sstream>
using namespace std;


template <typename T> class Blob{
public:
    template<typename It> Blob(It b, It e);

private:
    shared_ptr<vector<T>> data;
};

template <typename T>
template <typename It>
Blob<T>::Blob(It b, It e):data(make_shared<vector<T>>(b, e)) {}

int main(){
    int ia[] = {0, 1, 2, 3, 4};
    vector<long> vi = {0, 1, 2, 3, 4, 5, 6};
    list<const char *> w = {"now", "is", "the", "time"};
    
    Blob<int> a1(begin(ia), end(ia));
    Blob<int> a2(vi.begin(), vi.end());
    Blob<string> a3(w.begin(), w.end());    

}

601 类型转换与模板类型参数

#include <iostream>
#include <vector>
#include <string>
#include <list>
#include <iterator>
#include <memory>
#include <fstream>
#include <algorithm>
#include <functional>
#include <map>
#include <set>
#include <sstream>
using namespace std;


template <typename T> T fobj(T t1, T t2){
    return t1;
}
template <typename T> T fref(const T& t1, const T& t2){
    return t1;
}



int main(){
    string s1("a value");
    const string s2("another value");
    fobj(s1, s2);
    fref(s1, s2);

    int a[10], b[42];
    fobj(a, b);
    // reference will not convert to pointer
    // fref(a, b);

}

602 推断形参类型时候需要与模板定义中的关系一样

#include <iostream>
#include <vector>
#include <string>
#include <list>
#include <iterator>
#include <memory>
#include <fstream>
#include <algorithm>
#include <functional>
#include <map>
#include <set>
#include <sstream>
using namespace std;


template <typename A, typename B>
int flexibleCompare(const A& v1, const B& v2){
    if (v1<v2) return -1;
    if (v2<v1) return 1;
    return 0;
}


int main(){
    long lng=2048;
    cout << flexibleCompare(lng, 1024) << endl;

}

602 普通实参的类型转换

#include <iostream>
#include <vector>
#include <string>
#include <list>
#include <iterator>
#include <memory>
#include <fstream>
#include <algorithm>
#include <functional>
#include <map>
#include <set>
#include <sstream>
using namespace std;


template <typename T> ostream &print(ostream &os, const T& obj){
    return os << obj << endl;
}


int main(){
    print(cout,42);
    ofstream f("output");
    print(f, 10); // create output and write 10 inside

}

604 显式的指定模板实参类型

#include <iostream>
#include <vector>
#include <string>
#include <list>
#include <iterator>
#include <memory>
#include <fstream>
#include <algorithm>
#include <functional>
#include <map>
#include <set>
#include <sstream>
using namespace std;


template <typename T1, typename T2, typename T3>
T3 alternative_sum(T2 t2, T1 t1){
    return t2;
}


int main(){
    int i = 1; long lng = 2;
    // can not deduce T3
//    auto val3 = alternative_sum<long long>(i, lng);
    auto val2 = alternative_sum<long long, int, long>(i, lng);
    cout << val2 << endl;

}

604 显式的指定模板实参类型

#include <iostream>
#include <vector>
#include <string>
#include <list>
#include <iterator>
#include <memory>
#include <fstream>
#include <algorithm>
#include <functional>
#include <map>
#include <set>
#include <sstream>
using namespace std;


template <typename T, typename F=less<T>>
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;
}


int main(){
    // error params not match
//    bool i = compare(0, 42.2);
    long lng = 9;
    // 两个参数强制转换成long
    compare<long>(lng, 1024); // long, long
    // 两个参数强制转换成int
    compare<int>(lng, 1024); // int, int
    return 0;

}

604 返回类型根据参数去自动推断

#include <iostream>
#include <vector>
#include <string>
#include <list>
#include <iterator>
#include <memory>
#include <fstream>
#include <algorithm>
#include <functional>
#include <map>
#include <set>
#include <sstream>
using namespace std;


template <typename It>
auto fcn(It beg, It end) -> decltype(*beg){
    return *beg;
}

template <typename It>
auto fcn2(It beg, It end)->typename remove_reference<decltype(*beg)>::type{
    return *beg;
}

int main(){
    vector<int> v1 = {1, 2, 3, 4, 5};
    vector<string> ca = {"hi", "bye"};

    cout << fcn(v1.begin(), v1.end())<< endl;
    cout << fcn(ca.begin(), ca.end()) << endl;

    cout << fcn2(v1.begin(), v1.end()) << endl;

    return 0;

}

607 函数指针和实参推断

#include <iostream>
#include <vector>
#include <string>
#include <list>
#include <iterator>
#include <memory>
#include <fstream>
#include <algorithm>
#include <functional>
#include <map>
#include <set>
#include <sstream>
using namespace std;


template <typename T> int compare(const T&, const T&);
int (*pf1)(const int&, const int&) = compare;

void func(int(*) (const string&, const string&));
void func(int(*) (const int&, const int&));



int main(){
    func(compare<int>);
    
    return 0;

}

608 模板参数左值和右值的问题

#include <iostream>
#include <vector>
#include <string>
#include <list>
#include <iterator>
#include <memory>
#include <fstream>
#include <algorithm>
#include <functional>
#include <map>
#include <set>
#include <sstream>
using namespace std;


template <typename T> void f1(T&){};
template <typename T> void f3(T&&){};



int main(){
    int i=1;
    f1(i);
    const int ci = 2;
    f1(ci);
    // error
//    f1(2);
    f3(2);
    return 0;
}

609 接受右值引用模板函数的两种特例

#include <iostream>
#include <vector>
#include <string>
#include <list>
#include <iterator>
#include <memory>
#include <fstream>
#include <algorithm>
#include <functional>
#include <map>
#include <set>
#include <sstream>
using namespace std;

template <typename T>
T fcn(T t){
    return t+1;
}

template <typename T>
void f3(T&& val){
    T t = val; // copy
    t = fcn(t);

    cout << "t: " << t << endl;
    cout << "val: " << val << endl;

    if (val == t){

    }
}


int main(){


    f3(42); // t 43 val 42

    int a =42;
    f3(a);
    cout << "a: " << a << endl; // t 43, val 43 a 43
    return 0;
}

614 引用的转发

#include <iostream>
#include <vector>
#include <string>
#include <list>
#include <iterator>
#include <memory>
#include <fstream>
#include <algorithm>
#include <functional>
#include <map>
#include <set>
#include <sstream>
using namespace std;

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

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

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

//void g(int &&i, int &j){
//    cout << i << " " << j << endl;
//}



int main(){
    int a = 42;
    f(42, a);
    cout << a << endl; //43

    a = 42;
    flip1(f, a, 42);
    cout << a << endl;  // 42

    a = 42;
    flip2(f, a, 42);
    cout << a << endl;  // 43

    // error
//    a = 42;
//    flip2(g, a, 42); // 43
//    cout << a << endl;  // 42

    return 0;
}

614 翻转函数的终极版本

#include <iostream>
#include <vector>
#include <string>
#include <list>
#include <iterator>
#include <memory>
#include <fstream>
#include <algorithm>
#include <functional>
#include <map>
#include <set>
#include <sstream>
using namespace std;


void g(int &&i, int &j){
    cout << i << " " << ++j << endl;
}

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

int main(){

    int a = 42;
    flip(g, a, 42); 
    cout << a << endl;  // 43
    return 0;
}

616 模板的重载

#include <iostream>
#include <vector>
#include <string>
#include <list>
#include <iterator>
#include <memory>
#include <fstream>
#include <algorithm>
#include <functional>
#include <map>
#include <set>
#include <sstream>
using namespace std;


template <typename T> string debug_rep(const T &t){
    ostringstream ret;
    ret << t;
    return ret.str();
}

template <typename T> string debug_rep(T *p){
    ostringstream ret;
    ret << "pointer: " << p;
    if (p){
        ret << " " << debug_rep(*p);
    } else{
        ret << " null pointer";
    }
    return ret.str();
}


int main(){
    string s("hi");
    cout << debug_rep(s) << endl;   // hi 

    cout << debug_rep(&s) << endl; //pointer: 0034F7F4 hi
    return 0;
}

615 优先选择普通函数而非模板

#include <iostream>
#include <vector>
#include <string>
#include <list>
#include <iterator>
#include <memory>
#include <fstream>
#include <algorithm>
#include <functional>
#include <map>
#include <set>
#include <sstream>
using namespace std;


template <typename T> string debug_rep(const T &t){
    ostringstream ret;
    ret << t;
    return ret.str();
}

string debug_rep(const string &s){
    return '"' + s + '"';
}





int main(){
    string s("hi");
    cout << debug_rep(s) << endl;   // "hi"
    return 0;
}

619 可变参数模板

#include <iostream>
#include <vector>
#include <string>
#include <list>
#include <iterator>
#include <memory>
#include <fstream>
#include <algorithm>
#include <functional>
#include <map>
#include <set>
#include <sstream>
using namespace std;


template <typename T, typename... Args>
void foo(const T &t, const Args& ... rest);


int main(){
    int i = 0;
    double d = 3.14;
    string s = "how now brown cow";
    foo(i, s, 42, d);
    foo(s, 42, "hi");
    foo("hi");
    return 0;
}

619 确定参数包的大小

#include <iostream>
#include <vector>
#include <string>
#include <list>
#include <iterator>
#include <memory>
#include <fstream>
#include <algorithm>
#include <functional>
#include <map>
#include <set>
#include <sstream>
using namespace std;


template<typename ... Args>
void g(Args ... args){
    cout << sizeof...(Args) << endl;
    cout << sizeof...(args) << endl;
}


int main(){
    g(1, "gaa", 1.3); //3
    return 0; // 3
}

620 递归调用可变参数模板

#include <iostream>
#include <vector>
#include <string>
#include <list>
#include <iterator>
#include <memory>
#include <fstream>
#include <algorithm>
#include <functional>
#include <map>
#include <set>
#include <sstream>
using namespace std;


template<typename T>
ostream &print(ostream &os, const T &t){
    return os << t;
}

// recursive calling
template <typename T, typename ... Args>
ostream &print(ostream &os, const T &t, const Args ... rest){
    os << t << ", ";
    return print(os, rest...);
}

int main(){
    print(cout, 1, "gaa", 1.3);
    return 0;
}

622 包的扩展,把参数包里面的每一个参数应用到某个函数中

#include <iostream>
#include <vector>
#include <string>
#include <list>
#include <iterator>
#include <memory>
#include <fstream>
#include <algorithm>
#include <functional>
#include <map>
#include <set>
#include <sstream>
using namespace std;


template<typename T>
ostream &print(ostream &os, const T &t){
    return os << t;
}

// recursive calling
template <typename T, typename ... Args>
ostream &print(ostream &os, const T &t, const Args ... rest){
    os << t << ", ";
    return print(os, rest...);
}

template <typename T>
string debug_rep(T& t){
    ostringstream ret;
    ret << t + 1;
    return ret.str();
}

template <typename... Args>
ostream &errorMsg(ostream &os, const Args&... rest){
    return print(os, debug_rep(rest)...);
}


int main(){
    errorMsg(cout, 1, 2, 3, 4, 5); // 2, 3, 4, 5, 6
    return 0;
}

624 转发参数包

#include <iostream>
#include <vector>
#include <string>
#include <list>
#include <iterator>
#include <memory>
#include <fstream>
#include <algorithm>
#include <functional>
#include <map>
#include <set>
#include <sstream>
using namespace std;


template<typename... Args>
void fun(Args&&... args){
    work(std::forward<Args>(args)...);
}


int main(){
    return 0;
}

625 模板的特例化

#include <iostream>
#include <vector>
#include <string>
#include <list>
#include <iterator>
#include <memory>
#include <fstream>
#include <algorithm>
#include <functional>
#include <map>
#include <set>
#include <sstream>
using namespace std;


template <typename T> int compare(const T&, const T&){
    cout << "common type" << endl;
    return 1;
}

template<size_t N, size_t M>
int compare(const char (&)[N], const char (&)[M])
{
    cout << "special type" << endl;
    return 0;
}


int main(){
    const char *p1 = "hi", *p2 = "mom";
    compare(p1, p2); // common type
    compare("hi", "mom"); // common type


    return 0;
}

625 函数模板特例化

#include <iostream>
#include <vector>
#include <string>
#include <list>
#include <iterator>
#include <memory>
#include <fstream>
#include <algorithm>
#include <functional>
#include <map>
#include <set>
#include <sstream>
using namespace std;


template <typename T> int compare(const T&, const T&){
    cout << "common type" << endl;
    return 1;
}


// 函数模板特例化
template <>
int compare(const char* const &p1, const char* const &p2){
    return 2
}


int main(){
    const char *p1 = "hi", *p2 = "mom";
    compare(p1, p2); // common type
    compare("hi", "mom"); // common type


    return 0;
}

628 类模板部分特例化

#include <iostream>
#include <vector>
#include <string>
#include <list>
#include <iterator>
#include <memory>
#include <fstream>
#include <algorithm>
#include <functional>
#include <map>
#include <set>
#include <sstream>
using namespace std;


template <class T>
struct book{
    typedef T type;
public:
    void debug(){
        cout << "normal version" << endl;
    }
};

template <class T>
struct book<T&>{
    typedef T type;
public:
    void debug(){
        cout << "left reference version" << endl;
    }
};

template <class T>
struct book<T&&>{
    typedef T type;
public:
    void debug(){
        cout << "right reference version" << endl;
    }
};


int main(){
    int i=42;
    int& j = i; 
    book<decltype(42)> a; // normal version
    a.debug();

    book<decltype(j)> b; //left reference version
    b.debug();

    book<decltype(move(i))> c; // right reference version
    c.debug();



    return 0;
}

629 特例化类成员

#include <iostream>
#include <vector>
#include <string>
#include <list>
#include <iterator>
#include <memory>
#include <fstream>
#include <algorithm>
#include <functional>
#include <map>
#include <set>
#include <sstream>
using namespace std;


template <typename T> struct Foo{
    Foo(const T &t):mem(t){}
    void Bar(){
        cout << "normal bar" << endl;
    }
    T mem;
};

template<>
void Foo<int>::Bar() {
    cout << "special bar" << endl;
}


int main(){
    Foo<int> f1(2);
    f1.Bar(); // special bar

    Foo<string> f2("ah");
    f2.Bar(); // normal bar
    return 0;
}

16.63

#include <iostream>
#include <vector>
#include <string>
#include <list>
#include <iterator>
#include <memory>
#include <fstream>
#include <algorithm>
#include <functional>
#include <map>
#include <set>
#include <sstream>
using namespace std;


template <typename T>
struct Sat{
    Sat(vector<T> t):vec(t){};
    int cal(T n){
        return 0;
    }
private:
    vector<T> vec;
    int sum = 0;
};

template<>
int Sat<int>::cal(int n) {
    for (int val:vec){
        if (val==n){
            sum+=1;
        }
    }
    return sum;
}

template<>
int Sat<string>::cal(string n) {
    for (string val:vec){
        if (val==n){
            sum+=1;
        }
    }
    return sum;
}



int main(){
    vector<int> test1 = {1, 2, 1, 2, 3, 1};
    Sat<int> s1(test1);
    cout << s1.cal(1) << endl; // 3

    vector<string> test2 = {"a", "b", "a", "c", "a", "a"};
    Sat<string> s2(test2);
    cout << s2.cal("a") << endl; // 4

    return 0;
}

16.64

#include <iostream>
#include <vector>
#include <string>
#include <list>
#include <iterator>
#include <memory>
#include <fstream>
#include <algorithm>
#include <functional>
#include <map>
#include <set>
#include <sstream>
using namespace std;


template <typename T>
struct Sat{
    Sat(vector<T> t):vec(t){};
    int cal(T n){
        return 0;
    }
private:
    vector<T> vec;
    int sum = 0;
};

template<>
int Sat<int>::cal(int n) {
    for (int val:vec){
        if (val==n){
            sum+=1;
        }
    }
    return sum;
}

template<>
int Sat<string>::cal(string n) {
    for (string val:vec){
        if (val==n){
            sum+=1;
        }
    }
    return sum;
}


template<>
int Sat<const char *>::cal(const char *n) {
    for (const char *val:vec){
        if (strcmp(val, n)==0){
            sum +=1;
        }
    }
    return sum;
}



int main(){
    vector<int> test1 = {1, 2, 1, 2, 3, 1};
    Sat<int> s1(test1);
    cout << s1.cal(1) << endl; // 3

    vector<string> test2 = {"a", "b", "a", "c", "a", "a"};
    Sat<string> s2(test2);
    cout << s2.cal("a") << endl; // 4

    char ch1[] = "hello";
    char *p1 = ch1;
    char ch2[] = "world";
    char *p2 = ch2;

    vector<const char *> test3 = {p1, p2, p1};
    Sat<const char *> s3(test3);
    cout << s3.cal("hello") << endl;


    return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值