分享
 
 
 

Boost.bind的文档(翻译)

王朝other·作者佚名  2006-01-09
窄屏简体版  字體: |||超大  

bind.hpp

Contents Purpose 用途 Using bind with functions and function pointers 将bind用于函数和函数指针 Using bind with function objects 将bind用于函数对象 Using bind with pointers to members 将bind用于成员指针 Using nested binds for function composition 将嵌套的bind用于组合函数 Examples 示例 Using bind with standard algorithms 将bind用于标准算法 Using bind with Boost.Function 将bind用于Boost.Function Limitations 限制 Frequently Asked Questions 常见问题及解答 Why doesn't this compile? 为什么程序无法通过编译? Why does this compile? It should not. 为什么本应无法通过编译的程序通过了? What is the difference between bind(f, ...) and bind<R>(f, ...)? bind(f, ...)和bind<R>(f, ...)之间有什么区别? Does bind work with Windows API functions? 能否将bind用于Windows API函数? Does bind work with COM methods? 能否将bind用于COM方法? Does bind work with Mac toolbox functions? 能否将bind用于Mac toolbox函数? Does bind work with extern "C" functions? 能否将bind用于extern"C"函数? Why doesn't bind automatically recognize nonstandard functions? 为什么bind不能自动识别非标准函数? Troubleshooting 故障解决 Incorrect number of arguments 参数个数不正确 The function object cannot be called with the specified arguments 调用函数对象时没有使用指定的参数 Accessing an argument that does not exist 访问不存在的参数 Inappropriate use of bind(f, ...) 不适当的使用bind(f, ...) Inappropriate use of bind<R>(f, ...) 不适当的使用bind<R>(f, ...) Binding a nonstandard function 绑定非标准函数 const in signatures 声明中的const MSVC specific: using boost::bind; 针对MSVC:使用boost::bind MSVC specific: class templates shadow function templates 针对MSVC:类中包含的成员模板覆盖了外部的模板函数 MSVC specific: ... in signatures treated as type 针对MSVC:声明中的...被当作一个类型 Interface 接口 Synopsis 纲要 Common requirements 一般性需求 Common definitions 定义 bind Additional overloads 额外的重载 Implementation 实现 Files 文件 Dependencies 依赖性 Number of Arguments 参数个数 "__stdcall", "__fastcall", and "pascal" Support 对“__stdcall”、“__fastcall”和“pascal”的支持 visit_each support 对visit_each的支持 Acknowledgements 鸣谢 Purpose 用途 boost::bind is a generalization of the standard functions std::bind1st and std::bind2nd. It supports arbitrary function objects, functions, function pointers, and member function pointers, and is able to bind any argument to a specific value or route input arguments into arbitrary positions. bind does not place any requirements on the function object; in particular, it does not need the result_type, first_argument_type and second_argument_type standard typedefs.

boost::bind是标准库函数std::bind1st和std::bind2nd的一般化扩展。它支持任意的函数对象、函数、函数指针和类成员指针,它可以将特定的值绑定到任意一个参数或指定的位置。bind没有对函数对象提出任何要求,特别的,它不需要标准中定义的result_type、first_argument_type和second_argument_type等类型。

Using bind with functions and function pointers 将bind用于函数和函数指针 Given these definitions:

假定有如下定义:

int f(int a, int b) { return a + b; } int g(int a, int b, int c) { return a + b + c; }

bind(f, 1, 2) will produce a "nullary" function object that takes no arguments and returns f(1, 2). Similarly, bind(g, 1, 2, 3)() is equivalent to g(1, 2, 3).

bind(f, 1, 2)生成一个“无参数”的函数对象,这个函数对象不需要参数,返回值为f(1, 2)。类似的,bind(g, 1, 2, 3)()等价于g(1, 2, 3)。

It is possible to selectively bind only some of the arguments. bind(f, _1, 5)(x) is equivalent to f(x, 5); here _1 is a placeholder argument that means "substitute with the first input argument." 你可以有选择的只绑定某几个参数。bind(f, _1, 5)(x)等价于f(x, 5); 这里_1是一个占位符,表示“替换为第一个参数”(在这里为5)。 For comparison, here is the same operation expressed with the standard library primitives:

和标准库中提供的操作原语相比较:

std::bind2nd(std::ptr_fun(f), 5)(x);

bind covers the functionality of std::bind1st as well:

bind涵盖了std::bind1st的功能:

std::bind1st(std::ptr_fun(f), 5)(x); // f(5, x) bind(f, 5, _1)(x); // f(5, x)

bind can handle functions with more than two arguments, and its argument substitution mechanism is more general:

bind可以处理多于两个参数的函数,而且它的参数替换机制更为通用。

bind(f, _2, _1)(x, y); // f(y, x) bind(g, _1, 9, _1)(x); // g(x, 9, x) bind(g, _3, _3, _3)(x, y, z); // g(z, z, z) bind(g, _1, _1, _1)(x, y, z); // g(x, x, x)

Note that, in the last example, the function object produced by bind(g, _1, _1, _1) does not contain references to any arguments beyond the first, but it can still be used with more than one argument. Any extra arguments are silently ignored, just like the first and the second argument are ignored in the third example.

注意最后一个例子,bind(g, _1, _1, _1)生成的函数对象并不包含除第一个参数以外的其它参数,但是它仍然可以使用多个参数。任何多余的参数将会被忽略,正如在第三个例子中的第一个和第二个参数一样。

The arguments that bind takes are copied and held internally by the returned function object. For example, in the following code:

bind生成的函数对象在内部保持了一份参数的拷贝。例如下面的代码:

int i = 5; bind(f, i, _1);

a copy of the value of i is stored into the function object. boost::ref and boost::cref can be used to make the function object store a reference to an object, rather than a copy:

返回的函数对象中保存的是i的副本。boost::refboost::cref可以用来生成对象的引用,而不是副本:

int i = 5; bind(f, ref(i), _1);

Using bind with function objects 将bind用于函数对象 bind is not limited to functions; it accepts arbitrary function objects. In the general case, the return type of the generated function object's operator() has to be specified explicitly (without a typeof operator the return type cannot be inferred):

bind不仅能用于函数,而且还可以用于任意的函数对象。一般情况下,必须明确指定函数对象中的operator()成员的返回值类型(对于不支持typeof运算符的编译器,无法推断返回值的类型):

struct F { int operator()(int a, int b) { return a - b; } bool operator()(long a, long b) { return a == b; } }; F f; int x = 104; bind<int>(f, _1, _1)(x); // f(x, x), i.e. zero

Some compilers have trouble with the bind<R>(f, ...) syntax. For portability reasons, an alternative way to express the above is supported:

一些编译器无法正确处理bind<R>(f, ...)的形式。出于可移植性的考虑,可以使用另外一种表达方式:

boost::bind(boost::type<int>(), f, _1, _1)(x);

Note, however, that the alternative syntax is provided only as a workaround. It is not part of the interface.

需要注意的是,这种格式仅仅是为了兼容性而提供的一种解决方案。它并不是接口的一部分。

When the function object exposes a nested type named result_type, the explicit return type can be omitted:

如果函数对象内包含了一个叫做result_type的类型定义,那么返回值类型的声明可以省略:

int x = 8; bind(std::less<int>(), _1, 9)(x); // x < 9

[Note: the ability to omit the return type is not available on all compilers.]

[注意:并不是所有编译器都支持这种省略返回值类型的方式]

Using bind with pointers to members 将bind用于类成员 Pointers to member functions and pointers to data members are not function objects, because they do not support operator(). For convenience, bind accepts member pointers as its first argument, and the behavior is as if boost::mem_fn has been used to convert the member pointer into a function object. In other words, the expression

成员函数指针和成员变量指针不是函数对象,因为它们不支持operator()。出于方便起见,可以将成员指针作为bind的第一个参数,此时的行为相当于使用boost::mem_fn将成员指针转化为函数对象。换句话说,表达式:

bind(&X::f, args)

is equivalent to

等价于:

bind<R>(mem_fn(&X::f), args)

where R is the return type of X::f (for member functions) or a const reference to the type of the member (for data members.)

在这里,R是X::f的返回值类型(如果X::f是成员函数),或者是它的const引用(如果X::f是成员变量)。

[Note: mem_fn creates function objects that are able to accept a pointer, a reference, or a smart pointer to an object as its first argument; for additional information, see the mem_fn documentation.]

[注意:mem_fn创建的函数对象可以把对象指针、对象引用,或者对象的智能指针(smart pointer)作为它的第一个参数,详情请参阅mem_fn的文档。]

Example:

例如:

struct X { bool f(int a); }; X x; shared_ptr<X> p(new X); int i = 5; bind(&X::f, ref(x), _1)(i); // x.f(i) bind(&X::f, &x, _1)(i); //(&x)->f(i) bind(&X::f, x, _1)(i); // (internal copy of x).f(i) bind(&X::f, p, _1)(i); // (internal copy of p)->f(i)

The last two examples are interesting in that they produce "self-contained" function objects. bind(&X::f, x, _1) stores a copy of x. bind(&X::f, p, _1) stores a copy of p, and since p is a boost::shared_ptr, the function object retains a reference to its instance of X and will remain valid even when p goes out of scope or is reset().

后两个例子的有趣之处在于它们创建了“自包含”的函数对象。bind(&X::f, x, _1)保存了一份x的副本。bind(&X::f, p, _1)保存了一份p的副本,由于p是一个boost::shared_ptr,所以函数对象中保存的X的实例即使在p超出了作用域或者调用了reset()之后依然有效。

Using nested binds for function composition 将嵌套的bind用于组合函数 Some of the arguments passed to bind may be nested bind expressions themselves:

可以将bind表达式作为传递给bind的参数:

bind(f, bind(g, _1))(x); // f(g(x))

The inner bind expressions are evaluated, in unspecified order, before the outer bind when the function object is called; the results of the evaluation are then substituted in their place when the outer bind is evaluated. In the example above, when the function object is called with the argument list (x), bind(g, _1)(x) is evaluated first, yielding g(x), and then bind(f, g(x))(x) is evaluated, yielding the final result f(g(x)).

当调用这个函数对象时,先对内部的bind表达式求值,得出的结果再对外部的bind求值时被替换。在上面的例子中,当调用这个函数对象时,使用了参数表(x),先求出bind(g, _1)(x)的值,结果为g(x),然后再求出bind(f, g(x))(x)的值,结果为f(g(x))。

[译注:说实话这一段我没看懂,我总觉得应该是bind(f, bind(g, _1)(x)),也就是说那个参数表(x)是给bind(g, _1)提供的。]

This feature of bind can be used to perform function composition. See bind_as_compose.cpp for an example that demonstrates how to use bind to achieve similar functionality to Boost.Compose.

bind的这一特性可被用来进行函数组合。bind_as_compose.cpp中的例子演示了如何使用bind实现类似于Boost.Compose的功能。

Note that the first argument - the bound function object - is not evaluated, even when it's a function object that is produced by bind or a placeholder argument, so the example below does not work as expected:

请注意,第一个参数——被绑定的函数对象——并不被求值,即使它是一个bind生成的函数对象或者一个占位符,所以下面的例子并不能像预期的那样工作:

typedef void (*pf)(int); std::vector<pf> v; std::for_each(v.begin(), v.end(), bind(_1, 5));

The desired effect can be achieved via a helper function object apply that applies its first argument, as a function object, to the rest of its argument list. For convenience, an implementation of apply is provided in the boost/bind/apply.hpp header file. Here is how the modified version of the previous example looks like:

可一个用以的辅助函数对象apply达到目的。apply将它的第一个参数当作一个函数对象,然后将参数表中的其它参数传递给它,出于方便起见,在boost/bind/apply.hpp中包含了一个apply的实现。下面是前一个例子修改后的版本:

typedef void (*pf)(int); std::vector<pf> v; std::for_each(v.begin(), v.end(), bind(apply<void>(), _1, 5));

[译注:看起来受了Python的影响]

Sometimes it is necessary not to evaluate the first argument, but not to evaluate some of the other arguments, even when they are nested bind subexpressions. This can be achieved with the help of another function object, protect, that masks the type so that bind does not recognize and evaluate it. When called, protect simply forwards the argument list to the other function object unmodified.

有时我们要求不仅仅是第一个参数,而且其它的某些参数也不能被求值,即使它们是嵌套的bind表达式。此时我们可以使用另外一个辅助的函数对象protect,它屏蔽了参数的类型,所以bind不能识别并计算它。protect被调用时简单的把参数不加改动地传递给其他函数对象。

The header boost/bind/protect.hpp contains an implementation of protect. To protect a bind function object from evaluation, use protect(bind(f, ...)).

头文件boost/bind/protect.hpp中包含了一个protect的实现。使用protect(bind(f, ...))来免于对bind函数对象求值。

Examples 示例 Using bind with standard algorithms 将bind用于标准算法class image; class animation { public: void advance(int ms); bool inactive() const; void render(image & target) const; }; std::vector<animation> anims; template<class C, class P> void erase_if(C & c, P pred) { c.erase(std::remove_if(c.begin(), c.end(), pred), c.end()); } void update(int ms) { std::for_each(anims.begin(), anims.end(), boost::bind(&animation::advance, _1, ms)); erase_if(anims, boost::mem_fn(&animation::inactive)); } void render(image & target) { std::for_each(anims.begin(), anims.end(), boost::bind(&animation::render, _1, boost::ref(target))); }

Using bind with Boost.Function 将bind用于Boost.Functionclass button { public: boost::function<void> onClick; }; class player { public: void play(); void stop(); }; button playButton, stopButton; player thePlayer; void connect() { playButton.onClick = boost::bind(&player::play, &thePlayer); stopButton.onClick = boost::bind(&player::stop, &thePlayer); }

Limitations 限制 The function objects generated by bind take their arguments by reference and cannot, therefore, accept non-const temporaries or literal constants. This is an inherent limitation of the C++ language, known as the forwarding problem.

bind生成的函数对象将绑定的参数作为引用来使用,所以它不能接受非const的临时对象或常量,这是C++的语言限制,也就是我们熟知的“the forwarding problem”。

The library uses signatures of the form

库中的声明有如下形式:

template<class T> void f(T & t);

to accept arguments of arbitrary types and pass them on unmodified. As noted, this does not work with non-const r-values.

它可以接受并不加修改的传递任意类型的参数。但是正如前面指出的那样,它不能与用非const的右值(r-value)。

[译注:也就是类似这样的问题,形如f(int&)的函数不能接受一个double参数,因为C++标准规定不能将一个非const引用绑定到rvalue上,而编译器产生的临时变量都是rvalue,在这里编译器从double参数创建了一个临时的int变量。]

An oft-proposed "solution" to this problem is to add an overload:

对于这个问题,一般建议的解决方法是添加一个重载函数:

template<class T> void f(T & t); template<class T> void f(T const & t);

Unfortunately, this (a) requires providing 512 overloads for nine arguments and (b) does not actually work for const arguments, both l- and r-values, since the two templates produce the exact same signature and cannot be partially ordered.

但是很不幸,这样做会造成两个问题:(a)如果有9个参数,则要求有512个重载函数(29);(b)对于const形参,这样做并不能工作,不管是左值(l-value)还是右值(r-value),因为两个模板会产生完全相同的定义式,所以不能进行局部重排 [译注:partial ordering,更加特化的定义式会被优先选择]。

[Note: this is a dark corner of the language, and the corresponding issue has not been resolved yet.]

[注意:这是语言的阴暗面,这个问题还没有被解决。]

[译注:这个问题可能会比较严重,即便提供了所有可能的重载,依然有可能出错:类似于下面的程序:

template <class T> void f(T &n1, T &n2) { cout << n1 << "\t" << n2 << endl; } template <class T> void f(T &n1, const T &n2) { cout << "const " << n1 << "\t" << n2 << endl; } template <class T> void f(const T &n1, T &n2) { cout << n1 << "\tconst " << n2 << endl; } template <class T> void f(const T &n1, const T &n2) { cout << "const " << n1 << "\tconst " << n2 << endl; } int main() { double n=1; f(1, n); }

很明显大多数编译器(也包括我自己:-)都无法决定到底哪个重载形式更“正确”]

Frequently Asked Questions 常见问题及解答 Why doesn't this compile? 为什么程序无法通过编译? See the dedicated Troubleshooting section.

请参阅相应的“故障解决”章节。

Why does this compile? It should not. 为什么本应无法通过编译的程序通过了? Probably because you used the general bind<R>(f, ...) syntax, thereby instructing bind to not "inspect" f to detect arity and return type errors.

可能你使用了一般化的bind<R>(f, ...),所以bind没有检查f的参数个数和返回值类型。

What is the difference between bind(f, ...) and bind<R>(f, ...)? bind(f, ...)和bind<R>(f, ...)之间有什么区别? The first form instructs bind to inspect the type of f in order to determine its arity (number of arguments) and return type. Arity errors will be detected at "bind time". This syntax, of course, places some requirements on f. It must be a function, function pointer, member function pointer, or a function object that defines a nested type named result_type; in short, it must be something that bind can recognize.

第一种方式会让bind检查f的类型以确定它的参数个数(arity)和返回值类型。参数个数错误会在“绑定时刻”被检查出来。这种形式肯定会对f提出一些要求。f必须是一个函数、函数指针、成员函数指针,或者是一个包含了result_type类型定义的函数对象;简言之它必须是bind能认得的东西。

The second form instructs bind to not attempt to recognize the type of f. It is generally used with function objects that do not, or cannot, expose result_type, but it can also be used with nonstandard functions. For example, the current implementation does not automatically recognize variable-argument functions like printf, so you will have to use bind<int>(printf, ...). Note that an alternative bind(type<R>(), f, ...) syntax is supported for portability reasons.

第二种方式会让bind不要识别f的类型。一般仅用于没有或者无法提供result_type的函数对象,但是它也可以被用于非标准函数。比如,当前的实现不能自动识别像printf之类的可变参数函数,所以你必须使用bind<int>(printf, ...)。注意,提供另外一种形式bind(type<R>(), f, ...)仅仅是出于移植性的原因。

Another important factor to consider is that compilers without partial template specialization or function template partial ordering support cannot handle the first form when f is a function object, and in most cases will not handle the second form when f is a function (pointer) or a member function pointer.

还有另外一个重要因素,某些编译器不支持模板部分特化(partial specialization)或者函数模板局部重排(partial ordering),所以当f是一个函数对象,或者f是一个函数指针或成员函数指针时,编译器无法处理。

Does bind work with Windows API functions? 能否将bind用于Windows API函数? Yes, if you #define BOOST_BIND_ENABLE_STDCALL. An alternative is to treat the function as a generic function object and use the bind<R>(f, ...) syntax.

可以,你需要使用#define BOOST_BIND_ENABLE_STDCALL。另外一种方式是把函数当作一个一般函数对象(generic function object),然后使用bind<R>(f, ...)。

Does bind work with COM methods? 能否将bind用于COM方法? Yes, if you #define BOOST_MEM_FN_ENABLE_STDCALL.

可以,你需要使用#define BOOST_MEM_FN_ENABLE_STDCALL

Does bind work with Mac toolbox functions? 能否将bind用于Mac toolbox函数? Yes, if you #define BOOST_BIND_ENABLE_PASCAL. An alternative is to treat the function as a generic function object and use the bind<R>(f, ...) syntax.

可以,你需要使用#define BOOST_BIND_ENABLE_PASCAL。另外一种方式是把函数当作一个一般函数对象(generic function object),然后使用bind<R>(f, ...)。

Does bind work with extern "C" functions? 能否将bind用于extern "C"函数? Sometimes. On some platforms, pointers to extern "C" functions are equivalent to "ordinary" function pointers, so they work fine. Other platforms treat them as different types. A platform-specific implementation of bind is expected to handle the problem transparently; this implementation does not. As usual, the workaround is to treat the function as a generic function object and use the bind<R>(f, ...) syntax.

有时,在某些平台上,指向extern "C"函数的指针等价于一般的函数指针,此时一切正常。但在另外一些平台上,这些函数指针具有不同的类型。平台相关的bind实现可以透明的解决这个问题,但是当前的实现不行。一般情况下,解决方法是把函数当作一个一般函数对象(generic function object),然后使用bind<R>(f, ...)。

Why doesn't bind automatically recognize nonstandard functions? 为什么bind不能自动识别非标准函数? Non-portable extensions, in general, should default to off to prevent vendor lock-in. Had the appropriate macros been defined automatically, you could have accidentally taken advantage of them without realizing that your code is, perhaps, no longer portable. In addition, some compilers have the option to make __stdcall (__fastcall) their default calling convention, in which case no separate support would be necessary.

在缺省情况下,无法移植的扩展是被关闭的,以避免局限于特定的供应商。预先定义一些宏可能会让你在不知不觉中写出不可移植的代码。另外某些编译器可以通过命令行参数指定__stdcall(__fastcall)为缺省的函数调用方式,在这种情况下不需要一个单独的解决方案。

Troubleshooting 故障解决 Incorrect number of arguments 参数个数不正确 In a bind(f, a1, a2, ..., aN) expression, the function object f must be able to take exactly N arguments. This error is normally detected at "bind time"; in other words, the compilation error is reported on the line where bind() is invoked:

在一个bind(f, a1, a2, ..., aN)表达式中,函数对象f必须接受N个参数。这个错误一般会在“绑定时刻”被检测出来,换句话说,在调用bind()的程序行会产生一个编译错误。

int f(int, int); int main() { boost::bind(f, 1); // error, f takes two arguments boost::bind(f, 1, 2); // OK }

A common variation of this error is to forget that member functions have an implicit "this" argument:

造成这种错误的一个常见情况是忘记了成员函数有一个隐含的“this”参数:

struct X { int f(int); } int main() { boost::bind(&X::f, 1); // error, X::f takes two arguments boost::bind(&X::f, _1, 1); // OK }

The function object cannot be called with the specified arguments 调用函数对象时没有使用指定的参数 As in normal function calls, the function object that is bound must be compatible with the argument list. The incompatibility will usually be detected by the compiler at "call time" and the result is typically an error in bind.hpp on a line that looks like:

如同一般的函数调用,被绑定的函数对象必须具有一个兼容的参数列表。如果参数列表不兼容,编译器会在“调用时”检测出一个错误,一般情况下,这个错误会出现在bind.hpp中一行类似于这样的代码中:

return f(a[a1_], a[a2_]);

An example of this kind of error:

下面的示例程序会产生这种错误:

int f(int); int main() { boost::bind(f, "incompatible"); // OK so far, no call boost::bind(f, "incompatible")(); // error, "incompatible" is not an int boost::bind(f, _1); // OK boost::bind(f, _1)("incompatible"); // error, "incompatible" is not an int }

Accessing an argument that does not exist 访问不存在的参数 The placeholder _N selects the argument at position N from the argument list passed at "call time." Naturally, it is an error to attempt to access beyond the end of this list:

占位符_N在“调用时”从参数表中选择第N个参数。很自然,超出这个列表范围会出错。

int f(int); int main() { boost::bind(f, _1); // OK boost::bind(f, _1)(); // error, there is no argument number 1 }

The error is usually reported in bind.hpp, at a line similar to:

这个错误一般出现在bind.hpp中一行类似于这样的代码中:

return f(a[a1_]);

When emulating std::bind1st(f, a), a common mistake of this category is to type bind(f, a, _2) instead of the correct bind(f, a, _1).

常见错误出现于模拟std::bind1st(f, a)时,使用了bind(f, a, _2)而不是bind(f, a, _1)。

[译注:这句话没看懂,谁会笨的去用_2而不是_1?明明是bind1st嘛,难道是敲错了?]

Inappropriate use of bind(f, ...) 不适当的使用bind(f, ...) The bind(f, a1, a2, ..., aN) form causes automatic recognition of the type of f. It will not work with arbitrary function objects; f must be a function or a member function pointer.

使用bind(f, a1, a2, ..., aN)的形式会自动识别f的类型。它不能用于任意的函数对象,f必须是一个函数或者成员函数的指针。

It is possible to use this form with function objects that define result_type, but only on compilers that support partial specialization and partial ordering. In particular, MSVC up to version 7.0 does not support this syntax for function objects.

如果要将这种形式用于函数对象,则该函数对象必须包含一个result_type类型定义,但是仅在支持模板部分特化的编译器中才有效。MSVC直到7.0版(VC.Net 2002)不支持这种方式。

Inappropriate use of bind<R>(f, ...) 不适当的使用bind<R>(f, ...) The bind<R>(f, a1, a2, ..., aN) form supports arbitrary function objects.

使用bind<R>(f, a1, a2, ..., aN)的形式可以支持任意的函数对象,

It is possible (but not recommended) to use this form with functions or member function pointers, but only on compilers that support partial ordering. In particular, MSVC up to version 7.0 does not fully support this syntax for functions and member function pointers.

尽管可以对函数或成员函数指针使用这种形式(并不是推荐的做法),但是仅在支持模板局部重排的编译器中才有效。MSVC直到7.0版(VC.Net 2002)不支持这种方式。

Binding a nonstandard function 绑定非标准函数 By default, the bind(f, a1, a2, ..., aN) form recognizes "ordinary" C++ functions and function pointers. Functions that use a different calling convention, or variable-argument functions such as std::printf, do not work. The general bind<R>(f, a1, a2, ..., aN) form works with nonstandard functions.

缺省情况下,bind<R>(f, a1, a2, ..., aN)的形式可以识别“普通”的C++函数和函数指针。但不能用于使用不同调用约定的函数和类似于std::printf的可变参数函数。bind<R>(f, a1, a2, ..., aN)的形式可以用于这些非标准函数。

On some platforms, extern "C" functions, like std::strcmp, are not recognized by the short form of bind.

在某些平台上,简短形式的bind无法识别用extern "C"声明的函数,如std::strcmp。

See also "__stdcall" and "pascal" Support.

参见“对“__stdcall”、“__fastcall”和“pascal”的支持”。

const in signatures 声明中的const Some compilers, including MSVC 6.0 and Borland C++ 5.5.1, have problems with the top-level const in function signatures:

在某些编译器中,包括MSVC 6.0和Borland C++ 5.51,对于声明中有“顶级const(top-level const)”的函数会出问题。

int f(int const); int main() { boost::bind(f, 1); // error }

Workaround: remove the const qualifier from the argument.

解决方法:去掉参数中的const限定符。

[译注:这个“top-level const”没明白是什么东东]

MSVC specific: using boost::bind; 针对MSVC:使用boost::bind On MSVC (up to version 7.0), when boost::bind is brought into scope with an using declaration:

在MSVC中(直到7.0版),当使用using声明将boost::bind引入作用域中时:

using boost::bind;

the syntax bind<R>(f, ...) does not work. Workaround: either use the qualified name, boost::bind, or use an using directive instead:

会导致bind<R>(f, ...)无法使用。解决方法:使用限定名boost::bind,或者使用这样的using指令:

using namespace boost;

MSVC specific: class templates shadow function templates 针对MSVC:类中的成员模板覆盖了外部的模板函数 On MSVC (up to version 7.0), a nested class template named bind will shadow the function template boost::bind, breaking the bind<R>(f, ...) syntax. Unfortunately, some libraries contain nested class templates named bind (ironically, such code is often an MSVC specific workaround.)

在MSVC中(直到7.0版),如果一个类中有一个成员模板bind,则它会覆盖掉模板函数boost::bind,从而导致bind<R>(f, ...)无法使用。很不幸的是一些库中包含嵌套的名为bind的成员模板类(具有讽刺意味的是,这样的代码经常是针对MSVC的特定解决方案)。

The workaround is to use the alternative bind(type<R>(), f, ...) syntax.

解决方法是使用替换形式bind(type<R>(), f, ...)。

MSVC specific: ... in signatures treated as type 针对MSVC:声明中的...被当作一个类型 MSVC (up to version 7.0) treats the ellipsis in a variable argument function (such as std::printf) as a type. Therefore, it will accept the (incorrect in the current implementation) form:

在MSVC中(直到7.0版),可变参数函数(如std::printf)参数列表中的省略号被当作一个类型,从而导致它可以使用如下形式(在当前版本中本应是一个错误):

bind(printf, "%s\n", _1);

and will reject the correct version:

但是会拒绝正确的版本:

bind<int>(printf, "%s\n", _1);

Interface 接口 Synopsis 纲要namespace boost { // no arguments template<class R, class F> unspecified-1 bind(F f); template<class F> unspecified-1-1 bind(F f); template<class R> unspecified-2 bind(R (*f) ()); // one argument template<class R, class F, class A1> unspecified-3 bind(F f, A1 a1); template<class F, class A1> unspecified-3-1 bind(F f, A1 a1); template<class R, class B1, class A1> unspecified-4 bind(R (*f) (B1), A1 a1); template<class R, class T, class A1> unspecified-5 bind(R (T::*f) (), A1 a1); template<class R, class T, class A1> unspecified-6 bind(R (T::*f) () const, A1 a1); template<class R, class T, class A1> unspecified-6-1 bind(R T::*f, A1 a1); // two arguments template<class R, class F, class A1, class A2> unspecified-7 bind(F f, A1 a1, A2 a2); template<class F, class A1, class A2> unspecified-7-1 bind(F f, A1 a1, A2 a2); template<class R, class B1, class B2, class A1, class A2> unspecified-8 bind(R (*f) (B1, B2), A1 a1, A2 a2); template<class R, class T, class B1, class A1, class A2> unspecified-9 bind(R (T::*f) (B1), A1 a1, A2 a2); template<class R, class T, class B1, class A1, class A2> unspecified-10 bind(R (T::*f) (B1) const, A1 a1, A2 a2); // implementation defined number of additional overloads for more arguments } namespace { unspecified-placeholder-type-1 _1; unspecified-placeholder-type-2 _2; unspecified-placeholder-type-3 _3; // implementation defined number of additional placeholder definitions }

Common requirements 一般性需求 All unspecified-N types returned by bind are CopyConstructible. unspecified-N::result_type is defined as the return type of unspecified-N::operator().

bind返回的所有unspecified-N类型必须是可拷贝构造的(CopyConstructible),unspecified-N::result_type必须是unspecified-N::operator()的返回值类型。

All unspecified-placeholder-N types are CopyConstructible. Their copy constructors do not throw exceptions.

所有的unspecified-placeholder-N类型必须是可拷贝构造的(CopyConstructible),而且它们的构造函数不抛出任何异常。

Common definitions 定义 The function μ(x, v1, v2, ..., vm), where m is a nonnegative integer, is defined as:

函数μ(x, v1, v2, ..., vm), m是一个非负整数,被定义为:

x.get(), when x is of type boost::reference_wrapper<T> for some type T; x.get(),当x是boost::reference_wrapper<T>,T是某个类型; vk, when x is (a copy of) the placeholder _k for some positive integer k; vk,当x是某个占位符_k(或其副本),k是一个正整数; x(v1, v2, ..., vm) when x is (a copy of) a function object returned by bind; x(v1, v2, ..., vm) ,当x是一个bind返回的函数对象(或其副本); x otherwise. x,其他情况 bind template<class R, class F> unspecified-1 bind(F f) Returns: A function object λ such that the expression λ(v1, v2, ..., vm) is equivalent to f(), implicitly converted to R.

Throws: Nothing unless the copy constructor of F throws an exception.

template<class F> unspecified-1-1 bind(F f) Effects: Equivalent to bind<typename F::result_type, F>(f);

Notes: Implementations are allowed to infer the return type of f via other means as an extension, without relying on the result_type member.

template<class R> unspecified-2 bind(R (*f) ()) Returns: A function object λ such that the expression λ(v1, v2, ..., vm) is equivalent to f().

Throws: Nothing.

template<class R, class F, class A1> unspecified-3 bind(F f, A1 a1) Returns: A function object λ such that the expression λ(v1, v2, ..., vm) is equivalent to f(μ(a1, v1, v2, ..., vm)), implicitly converted to R.

Throws: Nothing unless the copy constructors of F or A1 throw an exception.

template<class F, class A1> unspecified-3-1 bind(F f, A1 a1) Effects: Equivalent to bind<typename F::result_type, F, A1>(f, a1);

Notes: Implementations are allowed to infer the return type of f via other means as an extension, without relying on the result_type member.

template<class R, class B1, class A1> unspecified-4 bind(R (*f) (B1), A1 a1) Returns: A function object λ such that the expression λ(v1, v2, ..., vm) is equivalent to f(μ(a1, v1, v2, ..., vm)).

Throws: Nothing unless the copy constructor of A1 throws an exception.

template<class R, class T, class A1> unspecified-5 bind(R (T::*f) (), A1 a1) Effects: Equivalent to bind<R>(boost::mem_fn(f), a1);

template<class R, class T, class A1> unspecified-6 bind(R (T::*f) () const, A1 a1) Effects: Equivalent to bind<R>(boost::mem_fn(f), a1);

template<class R, class T, class A1> unspecified-6-1 bind(R T::*f, A1 a1) Effects: Equivalent to bind<R const &>(boost::mem_fn(f), a1);

template<class R, class F, class A1, class A2> unspecified-7 bind(F f, A1 a1, A2 a2) Returns: A function object λ such that the expression λ(v1, v2, ..., vm) is equivalent to f(μ(a1, v1, v2, ..., vm), μ(a2, v1, v2, ..., vm)), implicitly converted to R.

Throws: Nothing unless the copy constructors of F, A1 or A2 throw an exception.

template<class F, class A1, class A2> unspecified-7-1 bind(F f, A1 a1, A2 a2) Effects: Equivalent to bind<typename F::result_type, F, A1, A2>(f, a1, a2);

Notes: Implementations are allowed to infer the return type of f via other means as an extension, without relying on the result_type member.

template<class R, class B1, class B2, class A1, class A2> unspecified-8 bind(R (*f) (B1, B2), A1 a1, A2 a2) Returns: A function object λ such that the expression λ(v1, v2, ..., vm) is equivalent to f(μ(a1, v1, v2, ..., vm), μ(a2, v1, v2, ..., vm)).

Throws: Nothing unless the copy constructors of A1 or A2 throw an exception.

template<class R, class T, class B1, class A1, class A2> unspecified-9 bind(R (T::*f) (B1), A1 a1, A2 a2) Effects: Equivalent to bind<R>(boost::mem_fn(f), a1, a2);

template<class R, class T, class B1, class A1, class A2> unspecified-10 bind(R (T::*f) (B1) const, A1 a1, A2 a2) Effects: Equivalent to bind<R>(boost::mem_fn(f), a1, a2);

Additional overloads 额外的重载 Implementations are allowed to provide additional bind overloads in order to support more arguments or different function pointer variations.

当前的实现允许为bind提供额外的重载,用以支持更多的参数个数或不同的函数指针。

Implementation 实现 Files 文件 boost/bind.hpp (main header) boost/bind/bind_cc.hpp (used by bind.hpp, do not include directly) boost/bind/bind_mf_cc.hpp (used by bind.hpp, do not include directly) boost/bind/bind_template.hpp (used by bind.hpp, do not include directly) boost/bind/arg.hpp (defines the type of the placeholder arguments) boost/bind/placeholders.hpp (defines the _1, _2, ... _9 placeholders) boost/bind/apply.hpp (apply helper function object) boost/bind/protect.hpp (protect helper function) boost/bind/make_adaptable.hpp (make_adaptable helper function) libs/bind/test/bind_test.cpp (test) libs/bind/bind_as_compose.cpp (function composition example) libs/bind/bind_visitor.cpp (visitor example) libs/bind/test/bind_stdcall_test.cpp (test with __stdcall functions) libs/bind/test/bind_stdcall_mf_test.cpp (test with __stdcall member functions) libs/bind/test/bind_fastcall_test.cpp (test with __fastcall functions) libs/bind/test/bind_fastcall_mf_test.cpp (test with __fastcall member functions) Dependencies 依赖性 Boost.Config boost/ref.hpp boost/mem_fn.hpp boost/type.hpp Number of Arguments 参数的个数 This implementation supports function objects with up to nine arguments. This is an implementation detail, not an inherent limitation of the design.

当前的实现支持最多带有9个参数的函数对象。这一限制是由实现细节,而不是设计造成的。

"__stdcall", "__fastcall", and "pascal" Support 对“__stdcall”、“__fastcall”和“pascal”的支持 Some platforms allow several types of (member) functions that differ by their calling convention (the rules by which the function is invoked: how are arguments passed, how is the return value handled, and who cleans up the stack - if any.)

某些平台允许使用一些与普通函数具有不同调用约定的函数。(调用约定指调用该函数时所采用的规则:如何传递参数,如何返回值,如何清理栈,等等)

For example, Windows API functions and COM interface member functions use a calling convention known as __stdcall.Borland VCL components use __fastcall. Mac toolbox functions use a pascal calling convention.

例如,Windows API函数和COM接口成员函数使用一种叫做__stdcall的调用约定。Borland VCL组件使用__fastcall。Mac toolbox函数使用pascal调用约定。

To use bind with __stdcall functions, #define the macro BOOST_BIND_ENABLE_STDCALL before including <boost/bind.hpp>.

要将bind用于__stdcall函数,在包含<boost/bind.hpp>前,定义BOOST_BIND_ENABLE_STDCALL宏。

To use bind with __stdcall member functions, #define the macro BOOST_MEM_FN_ENABLE_STDCALL before including <boost/bind.hpp>.

要将bind用于__stdcall成员函数,在包含<boost/bind.hpp>前,定义BOOST_MEM_FN_ENABLE_STDCALL宏。

To use bind with __fastcall functions, #define the macro BOOST_BIND_ENABLE_FASTCALL before including <boost/bind.hpp>.

要将bind用于__fastcall函数,在包含<boost/bind.hpp>前,定义BOOST_BIND_ENABLE_FASTCALL宏。

To use bind with __fastcall member functions, #define the macro BOOST_MEM_FN_ENABLE_FASTCALL before including <boost/bind.hpp>.

要将bind用于__fastcall成员函数,在包含<boost/bind.hpp>前,定义BOOST_MEM_FN_ENABLE_FASTCALL宏。

To use bind with pascal functions, #define the macro BOOST_BIND_ENABLE_PASCAL before including <boost/bind.hpp>.

要将bind用于pascal函数,在包含<boost/bind.hpp>前,定义BOOST_BIND_ENABLE_PASCAL宏。

[Note: this is a non-portable extension. It is not part of the interface.]

[注意:这是一个不可移植的扩展。它不属于接口的一部分。]

[Note: Some compilers provide only minimal support for the __stdcall keyword.]

[注意:某些编译器仅对__stdcall提供最小化的支持]

visit_each support 对visit_each的支持 Function objects returned by bind support the experimental and undocumented, as of yet, visit_each enumeration interface.

bind的返回的函数对象提供对visit_each的实验性支持,没有文档。

See bind_visitor.cpp for an example.

参见bind_visitor.cpp中的示例。

Acknowledgements 鸣谢 Earlier efforts that have influenced the library design:

The Binder Library by Jaakko J?rvi; The Lambda Library (now part of Boost) by Jaakko J?rvi and Gary Powell (the successor to the Binder Library); Extensions to the STL by Petter Urkedal. Doug Gregor suggested that a visitor mechanism would allow bind to interoperate with a signal/slot library.

John Maddock fixed a MSVC-specific conflict between bind and the type traits library.

Numerous improvements were suggested during the formal review period by Ross Smith, Richard Crossley, Jens Maurer, Ed Brey, and others. Review manager was Darin Adler.

The precise semantics of bind were refined in discussions with Jaakko J?rvi.

Dave Abrahams fixed a MSVC-specific conflict between bind and the iterator adaptors library.

Dave Abrahams modified bind and mem_fn to support void returns on deficient compilers.

Mac Murrett contributed the "pascal" support enabled by BOOST_BIND_ENABLE_PASCAL.

The alternative bind(type<R>(), f, ...) syntax was inspired by a discussion with Dave Abrahams and Joel de Guzman.

Copyright ? 2001, 2002 by Peter Dimov and Multi Media Ltd. Permission to copy, use, modify, sell and distribute this document is granted provided this copyright notice appears in all copies. This document is provided "as is" without express or implied warranty, and with no claim as to its suitability for any purpose.

 
 
 
免责声明:本文为网络用户发布,其观点仅代表作者个人观点,与本站无关,本站仅提供信息存储服务。文中陈述内容未经本站证实,其真实性、完整性、及时性本站不作任何保证或承诺,请读者仅作参考,并请自行核实相关内容。
2023年上半年GDP全球前十五强
 百态   2023-10-24
美众议院议长启动对拜登的弹劾调查
 百态   2023-09-13
上海、济南、武汉等多地出现不明坠落物
 探索   2023-09-06
印度或要将国名改为“巴拉特”
 百态   2023-09-06
男子为女友送行,买票不登机被捕
 百态   2023-08-20
手机地震预警功能怎么开?
 干货   2023-08-06
女子4年卖2套房花700多万做美容:不但没变美脸,面部还出现变形
 百态   2023-08-04
住户一楼被水淹 还冲来8头猪
 百态   2023-07-31
女子体内爬出大量瓜子状活虫
 百态   2023-07-25
地球连续35年收到神秘规律性信号,网友:不要回答!
 探索   2023-07-21
全球镓价格本周大涨27%
 探索   2023-07-09
钱都流向了那些不缺钱的人,苦都留给了能吃苦的人
 探索   2023-07-02
倩女手游刀客魅者强控制(强混乱强眩晕强睡眠)和对应控制抗性的关系
 百态   2020-08-20
美国5月9日最新疫情:美国确诊人数突破131万
 百态   2020-05-09
荷兰政府宣布将集体辞职
 干货   2020-04-30
倩女幽魂手游师徒任务情义春秋猜成语答案逍遥观:鹏程万里
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案神机营:射石饮羽
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案昆仑山:拔刀相助
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案天工阁:鬼斧神工
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案丝路古道:单枪匹马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:与虎谋皮
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:李代桃僵
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:指鹿为马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:小鸟依人
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:千金买邻
 干货   2019-11-12
 
推荐阅读
 
 
 
>>返回首頁<<
 
靜靜地坐在廢墟上,四周的荒凉一望無際,忽然覺得,淒涼也很美
© 2005- 王朝網路 版權所有