我读了限制的解释 http://www.boost.org/doc/libs/1_49_0/libs/bind/bind.html#Limitations 但我不太明白。 请问任何机构能给我一个例子吗?
让我用这个例子以另一种方式提出这个问题:
#include <boost/bind.hpp>
#include <boost/function.hpp>
#include <iostream>
#include <string>
using namespace std;
void Five(int &a, int &b, int &c, const int &d, const int &e) {
cerr << "In Five(): " << a + b + c + d + e << endl;
}
int main() {
int r = 1;
const int c = 100;
boost::bind(Five, _1, _2, _3, _4, _5)(r, r, r, c, r);
boost::bind(Five, _1, _2, _3, _4, _5)(r, r, r, r, c);
return 0;
}
这段代码编译得很好(没有C ++ 11支持)。那么,如果绑定在这种情况下工作,那么“限制”是指什么?有什么具体的例子吗?
另一个(更好)的例子:
#include <boost/bind.hpp>
#include <iostream>
#include <string>
using namespace std;
void Two(int &a, const int &c) {
cerr << "In Two(): " << a + c << endl;
}
void Three(int &a, int &b, const int &c) {
cerr << "In Three(): " << a + b + c << endl;
}
int Fun() { return 3; }
int main() {
int r = 1;
const int c = 100;
boost::bind(Two, _1, _2)(r, Fun()); // 1. OK
boost::bind(Three, _1, _2, _3)(r, r, c); // 2. OK
Three(r, r, Fun()); // 3. OK
boost::bind(Three, _1, _2, _3)(r, r, Fun()); // 4. CE!!
//??? Why 2 is OK but 4 is not ???
return 0;
}
答案 0 :(得分:2)
限制是指&#34;完美转发&#34;,它是通过启用c ++ 0x在最近的编译器上实现的(在编译时可能需要一些选项)。
如果编译器支持c ++ 0x,那么boost :: bind使用完美转发,否则忽略问题以避免函数重载爆炸!
例如:当使用2个参数绑定一个函数时,boost :: bind创建的仿函数对象将需要所有这些重载(如果没有c ++ 0x支持):
operator()(const A&, const B&)
operator()(const A&, B&)
operator()(A&, const B&)
operator()(A&, B&)
完美地前进。
这是一个详细描述完美转发问题的链接:http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2002/n1385.htm
不完美的转发将最终导致您:
答案 1 :(得分:0)
想象一下,你有以下泛型函数(它只是传递参数(称为“转发”)到内部函数callme
):
template <typename T> void f(T& t)
{
callme(t);
}
现在,假装callme
的定义如下:void callme(const int& i)
。
问题是callme(1)
可以工作,但f(1)
不会(这是因为rvalues不绑定到非const引用)。要解决此问题,您需要将f
更改为:f(const T& t)
。
但是,这引入了一个新问题。如果callme
定义如下:void callme(int& i)
,则会出现编译错误。解决方案是为f
设置两个重载,以同时使用f(const T& t)
和f(T& t)
。
现在,当函数只接受一个参数时,上述情况正常。但是,想象一个带有两个参数的函数,你必须进行4次重载:
f(const T1&, const T2&)
f(const T1&, T2&)
f(T1&, const T2&)
f(T1&, T2&)
In this article on msdn,它提到对于tr1::bind
,对于5个参数,总共需要63次重载!
我刚刚解释的内容称为forwarding problem,它已使用完美转发和右值引用在C++11
中解决。
Boost网站引用:
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.