深入理解模板3

1,类模板和函数模板的区别:
实例化类模板时总是需要尖括号并且提供所有的非默认参数.
对于函数模板经常可以省略掉模板参数,不允许使用默认模板参数.
2,若一个函数的模版参数是一个独立的模板参数,则调用它的时候一定要指定它的类型,因为它的类型无法从函数参数中推断出来.
实例代码:

#include <iostream>
#include <sstream>
using namespace std;

//返回类型是一个独立的参数
template<class T>
T fromString(const string str)
{
istringstream is(str);
T t;
is>>t;
return t;
}

template<class T>
string toString(const T& t)
{
ostringstream os;
os<<t;
return os.str();
}

int main()
{
int i = 1234;
cout << "i == \"" << toString(i) << "\"" << endl;
float x = 567.89;
cout << "x == \"" << toString(x) << "\"" << endl;


i = fromString<int>(string("1234"));
cout << "i == " << i << endl;
x = fromString<float>(string("567.89"));
cout << "x == " << x << endl;

return 0;
}

3,数组维数没有被作为函数参数类型的一部分进行传递,除非这个参数是指针或引用.
实例代码:

#include <cstddef>
using namespace std;

template<size_t R, size_t C, typename T>
void init1(T a[R][C])
{
for(size_t i = 0; i < R; ++i)
for(size_t j = 0; j < C; ++j)
a[i][j] = T();
}

template<size_t R, size_t C, class T>
void init2( T (&a)[R][C] ) //数组的引用作为参数传递
{
for(size_t i = 0; i < R; ++i)
for(size_t j = 0; j < C; ++j)
a[i][j] = T();
}

int main()
{
int a[10][20];
init1<10,20>(a); // 必须指定维数
init2(a); // 可以推断出来
//init1(a); //error: no matching function for call to `init1(int[10][20])'
}


4,模板函数重载:只要编译器可以分开.
实例代码:

#include <cstring>
#include <iostream>
using namespace std;

template<typename T> const T& myMin(const T& a, const T& b)
{
return (a < b) ? a : b;
}

const char* myMin(const char* a, const char* b)
{
return (strcmp(a, b) < 0) ? a : b;
}

double myMin(double x, double y)
{
return (x < y) ? x : y;
}

int main()
{
const char *s2 = "say \"Ni-!\"", *s1 = "knights who";
cout << myMin(1, 2) << endl; // (template)
cout << myMin(1.0, 2.0) << endl; // (double)
cout << myMin(1, 2.0) << endl; // (double)
cout << myMin(s1, s2) << endl; // (constchar*)
cout << myMin<>(s1, s2) << endl; // 强迫编译器使用模板
//这时比较的是两个字符串的地址.
}

5,多个重载函数可能发生冲突.
实例代码:

#include <iostream>
#include <algorithm>
#include <string>
using namespace std;

//写一个经过封装的函数模板,调用正确的tolower版本.
template<class T>
T strToLower(T& str)
{
//明确指定调用一个参数版本的tolower
return tolower(str);
}

int main()
{
string str("FJKDFJ");
transform(str.begin(),str.end(),str.begin(),strToLower<char>);
cout<<str<<endl;
}

6,模板函数结合容器对象的成员函数.
实例代码:

#include <iostream>
#include <vector>
#include <cstddef>
#include <algorithm>
using namespace std;

//容器类型,容器的对象类型,对象成员函数的返回类型
template<class Seq, class T, class R>
void apply(Seq& sq, R (T::*f)() const)
{
typename Seq::iterator it = sq.begin();
while(it != sq.end())
((*it++)->*f)();
}

//1个参数的const成员函数
template<class Seq, class T, class R, class A>
void apply(Seq& sq, R(T::*f)(A) const, A a) {
typename Seq::iterator it = sq.begin();
while(it != sq.end())
((*it++)->*f)(a);
}

//2个参数的const成员函数
template<class Seq, class T, class R, class A1, class A2>
void apply(Seq& sq, R(T::*f)(A1, A2) const, A1 a1, A2 a2)
{
typename Seq::iterator it = sq.begin();
while(it != sq.end())
((*it++)->*f)(a1, a2);
}

// Non-const, 0 arguments, any type of return value:
template<class Seq, class T, class R>
void apply(Seq& sq, R (T::*f)())
{
typename Seq::iterator it = sq.begin();
while(it != sq.end())
((*it++)->*f)();
}

// Non-const, 1 argument, any type of return value:
template<class Seq, class T, class R, class A>
void apply(Seq& sq, R(T::*f)(A), A a)
{
typename Seq::iterator it = sq.begin();
while(it != sq.end())
((*it++)->*f)(a);
}

// Non-const, 2 arguments, any type of return value:
template<class Seq, class T, class R,class A1, class A2>
void apply(Seq& sq, R(T::*f)(A1, A2), A1 a1, A2 a2)
{
typename Seq::iterator it = sq.begin();
while(it != sq.end())
((*it++)->*f)(a1, a2);
}

class Gromit
{
int arf;
int totalBarks;
public:
Gromit(int arf = 1) : arf(arf + 1), totalBarks(0) {}
void speak(int)
{
for(int i = 0; i < arf; i++)
{
std::cout << "arf! ";
++totalBarks;
}
cout << endl;
}
char eat(float) const
{
cout << "chomp!" << endl;
return 'z';
}
int sleep(char, double) const
{
cout << "zzz..." << endl;
return 0;
}
void sit() const
{
cout << "Sitting..." << endl;
}
};

int main()
{
vector<Gromit*> dogs;
for(size_t i = 0; i < 5; i++)
dogs.push_back(new Gromit(i));
apply(dogs, &Gromit::speak, 1);
apply(dogs, &Gromit::eat, 2.0f);
apply(dogs, &Gromit::sleep, 'z', 3.0);
apply(dogs, &Gromit::sit);
for_each(dogs.begin(),dogs.end(),ptr_fun(operator delete));
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值