5.10.1 容器元素的条件
STL容器的元素必须满足以下3个条件:
1. 必须可通过拷贝构造函数进行复制。副本与原本必须相等。所有容器都会在内部生成一个元素副本,并传回该暂时性副本,因此拷贝构造函数会被频繁地调用。所以 拷贝构造函数的性能应该尽可能优化。如果对象的拷贝必须耗费大量时间,可以选用[reference语义]来使用容器,因而避免拷贝任何对象。
2. 必须通过赋值运算符完成赋值动作。
3. 必须可以通过析构函数完成销毁动作。当容器元素被删除,它在容器内的副本将被销毁。因此析构函数绝不能被设计为private。此外,依C++惯例,析构函数绝不能抛出异常(throw exceptions)。
下列条件也应该获得满足:
1. 对序列式容器而言,元素的默认构造函数必须可用。我们可以在没有给予任何初值的情况下,创建一个非空容器,或增加容器的元素个数。
2. 对于某些动作,必须定义operator==以执行相等测试。如果有搜寻需求,这一点特别重要。
3. 在关联容器中,元素必须定义排序准则。预设情况下是operator<,通过function object less<>被调用。
8.1 The Concept of Function Objects
Function objects has three important advantages:
1. A function object might be smarter because it may have a state. In fact, you can have two
instances of the same function, represented by a function object, which may have
different states at the same time. This is not possible for ordinary functions.
2. Each function object has its own type. Thus, you can pass the type of a function object to
a template to specify a certain behavior, and you have the advantage that container types
with different function objects differ.
3. A function object is usually faster than a function pointer.
8.1.2 Function Objects with Internal State
Function objects are passed by value rather than by reference. Thus, the algorithm does not change the state of the function object.
To pass a function object by reference you simply have to qualify the call of the algorithm so that the function object type is a reference. For example:
generate_n<back_insert_iterator<list<int> >, int, IntSequence&> (back_inserter(coll), //start
4, //number of elements
seq); //generates values
8.1.4 Predicates versus Function Objects
A predicate should not change its state due to a call, and a copy of a predicate should have the same state as the original. To ensure that you can't change the state of a predicate due to a function call, you should declare operator () as constant member function.
To call member function for each element of a collection:
mem_fun_ref:当容器中存放的是对象实体时使用
mem_fun:当容器中存放的是对象的指针时使用
8.2.3 Function Adapters for Ordinary Functions
Another function adapter enables ordinary functions to be used from other function adapters:ptr_fun()
//find first string that is not empty
pos = find_if (coll.begin(), coll.end(), //range
bind2nd(ptr_fun(strcmp),"")); //search criterion
8.2.4 User-Defined Function Objects for Function Adapters
You can write your own function objects, but to use them in combination with function adapters they must meet certain requirements: They must provide type members for the type of their arguments and the result. The C++ standard library provides structures to make this more convenient:
template <class Arg, class Result>
struct unary_function {
typedef Arg argument_type;
typedef Result result_type;
};
template <class Argl, class Arg2, class Result>
struct binary_function {
typedef Argl first_argument_type;
typedef Arg2 second_argument_type;
typedef Result result_type;
};
Thus, by deriving your function object from one of these types you meet the requirements easily so that your function object becomes "adapter-able."
9.2.2 C1assification of Algorithms