boost.png (6897 bytes) Home Libraries People FAQ More

Member Function Adapters 成員函數適配器

The header functional.hpp includes improved versions of the full range of member function adapters from the the C++ Standard Library (§20.3.8):

頭文件 functional.hpp 包含了C++標準中各個成員函數適配器(§20.3.8)的改良版本:

as well as the corresponding overloaded helper functions

以及相應的重載輔助函數:

The following changes have been made to the adapters as specified in the Standard:

與標準中的規格相比,作出了如下修改:

first_argument_type

The standard specifies const_mem_fun1_t, for example, like this:

例如,標準規格的 const_mem_fun1_t 如下:

template <class S, class T, class A> class const_mem_fun1_t
: public binary_function<T*, A, S> {
public:
explicit const_mem_fun1_t(S (T::*p)(A) const);
S operator()(const T* p, A x) const;
};

Note that the first argument to binary_function is T* despite the fact that the first argument to operator() is actually of type const T*.

注意,binary_function 的第一個參數是 T*,而事實上 operator() 的第一個參數的類型是 const T*.

Does this matter? Well, consider what happens when we write

這有問題嗎?是的,如果我們這樣寫:

struct Foo { void bar(int) const; };
const Foo *cp = new Foo;
std::bind1st(std::mem_fun(&Foo::bar), cp);

We have created a const_mem_fun1_t object which will effectively contain the following

我們創建了一個 const_mem_fun1_t 對象,它包含了:

typedef Foo* first_argument_type;

The bind1st will then create a binder1st object that will use this typedef as the type of a member which will be initialised with cp. In other words, we will need to initialise a Foo* member with a const Foo* pointer! Clearly this is not possible, so to implement this your Standard Library vendor will have had to cast away the constness of cp, probably within the body of bind1st.

接著 bind1st 將創建一個 binder1st 對象,該對像使用這個 typedef 作為某個成員的類型,該成員將被初始化為 cp。換句話說,我們需要以一個 const Foo* 指針來初始化一個 Foo* 成員!這顯然是不可以的,為了實現它,你的標準庫供應商不得不將 cp 的常量性 cast 掉,這可能是在 bind1st 內部完成的。

This hack will not suffice with the improved binders in this library, so we have had to provide corrected versions of the member function adapters as well.

這一方法對於本庫的改良式 綁定器 是不行的,所以我們必須對成員函數適配器也提供修正的版本。

Argument Types 參數類型

The standard defines mem_fun1_t, for example, like this (§20.3.8 ¶2):

例如,標準的 mem_fun1_t 定義如下(§20.3.8 ¶2):

template <class S, class T, class A> class mem_fun1_t
: public binary_function<T*, A, S> {
public:
explicit mem_fun1_t(S (T::*p)(A));
S operator()(T* p, A x) const;
};

Note that the second argument to operator() is exactly the same type as the argument to the member function. If this is a value type, the argument will be passed by value and copied twice.

注意,operator() 的第二個參數與成員函數的參數是完全相同的類型。如果它是一個值類型,則該參數將被以值的方式傳遞,並複製兩次。

However, if we were to try and eliminate this inefficiency by instead declaring the argument as const A&, then if A were a reference type, we would have a reference to a reference, which is currently illegal (but see C++ core language issue number 106)

但是,如果我們試圖去消除這一低效率的操作,將參數的聲明改為 const A&, 那麼如果 A 是一個引用類型,則我們就有了一個引用的引用,當前這是非法的(不過可以參見一下 C++ 核心語言問題 106)

So the way in which we want to declare the second argument for operator() depends on whether or not the member function's argument is a reference. If it is a reference, we want to declare it simply as A; if it is a value we want to declare it as const A&.

所以,我們如果聲明 operator() 的第二個參數,要取決於成員函數的參數是否為引用。如果是,那麼我們只要將它聲明為 A; 如果不是,則我們應該將它聲明為 const A&.

The Boost call_traits class template contains a param_type typedef, which uses partial specialisation to make precisely this decision. By declaring the operator() as

Boost call_traits 類模板包含了一個 param_type typedef, 它使用偏特化來作出恰當的決定。通過將 operator() 聲明為:

S operator()(T* p, typename call_traits<A>::param_type x) const

we achieve the desired result - we improve efficiency without generating references to references.

我們就可以得到所希望的結果 - 我們改進了效率而且不會產生引用的引用。

Limitations 局限

The call traits template used to realise some improvements relies on partial specialisation, so these improvements are only available on compilers that support that feature. With other compilers, the argument passed to the member function (in the mem_fun1_t family) will always be passed by reference, thus generating the possibility of references to references.

call traits 模板的改進依賴於偏特化,所以這些改進只能在支持這一特性的編譯器上使用。對於其它編譯器,傳遞給成員函數(mem_fun1_t 族中的)的參數總是以引用方式傳遞的,所以有可能產生引用的引用。


Valid HTML 4.01 Transitional

Revised 02 December, 2006

Copyright c 2000 Cadenza New Zealand Ltd.

Distributed under the Boost Software License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)