From aef08dd0cdf5098281c5a1003e7c05a0abeb0843 Mon Sep 17 00:00:00 2001
From: Peter Dimov For convenience, the function objects produced by bind overload the
logical not operator Overloaded operators (new in Boost 1.33)
!
and the relational and logical operators ==
,
- !=
, <
, <=
, >
,
- >=
, &&
, ||
.!=
, <
, <=
, >
, >=
,
+ &&
, ||
.
!bind(f, ...) is equivalent to bind( logical_not(), bind(f, ...) ), where logical_not is a function object that takes one argument x and returns !x.
-bind(f, ...) op x, where op is a relational or logical operator, - is equivalent to bind( relation(), bind(f, ...), x ), where relation - is a function object that takes two arguments a and b and - returns a op b.
+bind(f, ...) op x, where op is a relational or + logical operator, is equivalent to bind( relation(), bind(f, ...), x ), + where relation is a function object that takes two arguments a + and b and returns a op b.
What this means in practice is that you can conveniently negate the result of bind:
std::remove_if( first, last, !bind( &X::visible, _1 ) ); // remove invisible objects
and compare the result of bind against a value:
std::find_if( first, last, bind( &X::name, _1 ) == "Peter" );
-std::find_if( first, last, bind( &X::name, _1 ) == "Peter" || bind( &X::name, _1 ) == "Paul" );
+std::find_if( first, last, bind( &X::name, _1 ) == "Peter" || bind( + &X::name, _1 ) == "Paul" );
against a placeholder:
bind( &X::name, _1 ) == _2
or against another bind expression:
@@ -384,10 +385,12 @@ void connect() }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.
+As a general rule, 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 in its + current (2003) incarnation, known as + the forwarding problem. (It will be fixed in the next standard, usually + called C++0x.)
The library uses signatures of the form
template<class T> void f(T & t); @@ -395,17 +398,17 @@ void connect()to accept arguments of arbitrary types and pass them on unmodified. As noted, this does not work with non-const r-values.
-An oft-proposed "solution" to this problem is to add an overload: +
On compilers that support partial ordering of function templates, a possible + solution 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. -
-[Note: this is a dark corner of the language, and the - corresponding issue has only recently been resolved.] +
Unfortunately, this requires providing 512 overloads for nine arguments, which + is impractical. The library chooses a small subset: for up to two arguments, it + provides the const overloads in full, for arities of three and more it provides + a single additional overload with all of the arguments taken by const + reference. This covers a reasonable portion of the use cases.
Frequently Asked Questions
Why doesn't this compile?