模板主要有函数模板和类模板。模板的参数决定了它的特性。每一个参数可以代表下面三者之一:
1. 类型(内建类型或用户自定义类型)
2. 编译时常量(如整型、指针和静态引用等,一般称这种参数为非类型参数)
3. 其它的模板。
默认参数类模板可以有,函数模板不能有。
模板类/函数声明和定义也能分开(之前看网上有人说不能分开),有两种方法:
1. 建立中间文件(.cpp)具体声明模板的类型。如:
//: C05:OurMin.h
#ifndef OURMIN_H
#define OURMIN_H
// The declaration of min()
template<typename T> const T& min(const T&, const T&);
#endif // OURMIN_H ///:~
// OurMin.cpp
#include "OurMin.h"
// The definition of min()
template<typename T> const T& min(const T& a, const T& b) {
return (a < b) ? a : b;
}
可以使用中间文件:
//: C05:MinInstances.cpp {O}
#include "OurMin.cpp"
// Explicit Instantiations for int and double
template const int& min<int>(const int&, const int&);
template const double& min<double>(const double&,
const double&);
///:~
2. 在头文件中使用export关键字声明(在实现文件中可以不使用,但最好使用,这样是好习惯)。
#include <algorithm>
#include <cstddef>
#include <functional>
#include <iostream>
#include <iterator>
using namespace std;
int main() {
int a[] = { 10, 20, 30 };
const size_t SIZE = sizeof a / sizeof a[0];
remove_copy_if(a, a + SIZE,
ostream_iterator<int>(cout, "/n"),
bind2nd(greater<int>(), 15)); }//bind2nd是模板函数,有两个参数:
//第一个是接受两个参数的内部函数,第二个是内部函数的第二个参数,第一个参数由a的//值传给bind2nd再传给内部函数。
常用模板生成函数:
Name |
Type |
Result produced |
Plus |
BinaryFunction |
arg1 + arg2 |
Minus |
BinaryFunction |
arg1 - arg2 |
Multiplies |
BinaryFunction |
arg1 * arg2 |
Divides |
BinaryFunction |
arg1 / arg2 |
Modulus |
BinaryFunction |
arg1 % arg2 |
Negate |
UnaryFunction |
- arg1 |
equal_to |
BinaryPredicate |
arg1 == arg2 |
not_equal_to |
BinaryPredicate |
arg1 != arg2 |
Greater |
BinaryPredicate |
arg1 > arg2 |
Less |
BinaryPredicate |
arg1 < arg2 |
greater_equal |
BinaryPredicate |
arg1 >= arg2 |
less_equal |
BinaryPredicate |
arg1 <= arg2 |
logical_and |
BinaryPredicate |
arg1 && arg2 |
Logical_or |
BinaryPredicate |
arg1 || arg2 |
logical_not |
UnaryPredicate |
!arg1 |
unary_negate |
Unary Logical |
!(UnaryPredicate(arg1)) |
binary_negate |
Binary Logical |
!(BinaryPredicate(arg1, arg2)) |
多重继承避免重名:子类中引用重名函数或变量时,使用using classA::name明确声名。
要使用多重继承(MI),必须同时满足两个条件:
1. 需要在新类中暴露两个基类的公共接口吗?(看看能不能通过依赖关系,在新类中只暴露其中一个基类的部分接口。)
2. 需要能够向所有基类向上映射吗?