template
class accumulation_traits;
template <>
class accumulation_traits {
public:
typedef int AccT;
static AccT zero() { return 0; }
};
template <>
class accumulation_traits {
public:
typedef int AccT;
static AccT zero() { return 0; }
};
template <>
class accumulation_traits {
public:
typedef long AccT;
static AccT zero() { return 0; }
};
template <>
class accumulation_traits {
public:
typedef double AccT;
//static const double zero = 0.0; //complier error
static AccT zero() { return 0; }
};
template
inline
typename accumulation_traits::AccT accum(T const* beg, T const* end)
{
typedef typename accumulation_traits::AccT AccT;
AccT total = accumulation_traits::zero();
while(beg != end){
total += *beg;
++beg;
}
return total;
}
int main()
{
int num[] = {1, 2, 3, 4, 5};
std::cout<<"average="<(&num[0], &num[5])<
template >
class accum_class {
public:
static typename AT::AccT accum(const T* beg, const T* end) {
typename AT::AccT total = AT::zero();
while(beg != end) {
total += *beg;
++beg;
}
return total;
}
};
template
inline
typename accumulation_traits::AccT accum(const T* beg, const T* end)
{
return accum_class::accum(beg, end);
}
template //其中第一个参数就是 trait 方案,有默认值,也可由用户提供
inline
typename Traits::AccT accum(const T* beg, const T* end)
{
return accum_class::accum(beg, end);
}
int main()
{
int num[] = {1, 2, 3, 4, 5};
std::cout<<"average="< >(&name[0],&name[length])/length<
1.对于T是自定义类型的,如果存在子类型则需要在模版内部加上typename
示例代码:
1
2
3
4
5
|
template
<
typename
T>
class
Myclass
{
typename
T::SubType *ptr;
//需要加上typename不然编译器可能误解为是静态对象SubType和ptr相乘
};
|
2.类模版里对基类成员函数的调用使用BASE::exit();和this->,避免调用的是外部全局函数,但是在vc6.0上面这条规则是先调用的BASE里面的函数。
示例代码:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
|
#include
#include
#include
using
namespace
std;
void
exit
()
{
cout <<
"hello world"
< }
template
<
typename
T>
class
BaseMyclass
{
public
:
void
exit
()
{
cout <<
"Base"
<
}
};
template
<
typename
T>
class
Myclass:
public
BaseMyclass
{
public
:
void
foo()
{
exit
();
}
};
int
main()
{
Myclass<
int
> m1;
m1.foo();
return
0;
}
|
3.成员模板,由于两种不同的类型之间的赋值不能使用类本身的接口,所以需要重新设计接口。
示例代码:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
|
#include
#include
#include
using
namespace
std;
template
<
typename
T>
class
Stack
{
public
:
template
<
typename
T2>
Stack
const
&);
};
template
<
typename
T>
template
<
typename
T2>
Stack
const
&op2)
{
}
int
main()
{
return
0;
}
|
调用时首先通过显式指定的模板类型实例化一个类,然后通过实例化一个成员函数,只是现在的成员函数是模板函数,然后根据调用的参数实例化成一个成员函数。
4.模板的模板参数,实际上是一个模板类,上面的成员模板实际上是一个模板函数。
代码示例:
1
2
3
4
5
6
|
template
<
typename
T,
template
<
typename
T>
class
CONT = vector>
class
Stack
{
public
:
};
|
5.零初始化,因为模板不知道类型所以我们无法用任何一个常量来初始化模板参数定义的变量。但是可以如下例子进行初始化
代码示例:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
|
#include
#include
#include
using
namespace
std;
template
<
typename
T>
void
foo()
{
T x = T();
}
template
<
typename
T>
class
Myclass
{
private
:
T x;
public
:
Myclass():x(T()){}
};
int
main()
{
foo<
int
>();
Myclass<
int
> m1;
return
0;
}
|
6.使用字符串作为函数模板的实参若是引用则需要字符串长度完全匹配
示例代码:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
|
template
<
typename
T>
inline
T&
const
max(T
const
& a,T
const
& b)
{
return
a > b ? a:b;
}
int
main()
{
cout << max(
"apple"
,
"peach"
)<
cout << max(
"apple"
,
"tomato"
)<
return
0;
}
|
若不为引用则不需要字符串长度完全一样,原因是参数会转换成字符串指针类型,属于相同的类型
示例代码:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
|
#include
#include
#include
using
namespace
std;
template
<
typename
T>
inline
T max(T a,T b)
{
return
a > b ? a:b;
}
int
main()
{
cout << max(
"apple"
,
"peach"
)<
cout << max(
"apple"
,
"tomato"
)<
return
0;
}
|
字符串作为实参的测试示例:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
|
template
<
typename
T>
void
ref(T
const
& x,T
const
& y)
{
cout <<
"x int the ref is "
<<
typeid
(x).name() < }
template
<
typename
T>
void
nonref(T x)
{
cout <<
"x int the noref is "
<<
typeid
(x).name() < }
int
main()
{
ref(
"hello"
);
nonref(
"hello"
);
return
0;
}
|