我有以下代码,可以在Visual Studio 2008 SP1下编译并运行。
#include <functional>
#include <iostream>
#include <boost/bind.hpp>
#include <boost/function.hpp>
#include <boost/scoped_ptr.hpp>
#include <boost/utility.hpp>
class NoncopyableObject : public boost::noncopyable
{
public:
NoncopyableObject(int x) : x_(x) {}
int getValue() const {return x_;}
private:
int x_;
};
template<class F>
class MenuItemDispatcher
{
public:
MenuItemDispatcher(F f) : f_(f) { }
void operator ()(NoncopyableObject& w) const
{
// Invoke the functor
f_(w);
}
private:
typedef boost::function1<void,NoncopyableObject&> FUNC;
FUNC f_;
};
void MenuItem()
{
std::cout << "in MenuItem()\n";
}
template<class F>
MenuItemDispatcher<F> MakeMenuItemDispatcher(F f)
{
return MenuItemDispatcher<F>(f);
}
int main()
{
NoncopyableObject obj(7);
MakeMenuItemDispatcher(boost::bind(&MenuItem))(obj);
}
如果我在main()中将boost :: bind更改为std :: tr1 :: bind,我会收到错误:
错误C2248:
'boost::noncopyable_::noncopyable::noncopyable'
:无法访问类'boost::noncopyable_::noncopyable'
中声明的私有成员。此诊断发生在编译器生成的函数
中'NoncopyableObject::NoncopyableObject(const NoncopyableObject &)'
所以它试图为NoncopyableObject生成一个拷贝构造函数。有人知道为什么会这样吗? MenuItemDispatcher的调用操作符接受对NoncopyableObject的引用,所以我很难看出出了什么问题。
答案 0 :(得分:4)
这似乎与MS Visual Studio(包括2010)和GNU gcc(我测试的4.4.1和4.5.2,两者都按照您预期的方式工作)中实现bind
的方式不同/ p>
根据您的定义
,请考虑以下代码auto b = boost::bind(&MenuItem);
NoncopyableObject obj(7);
b(obj); // OK in VS and GCC
用std :: bind替换boost :: bind(我使用的是2010,错误信息与你的2008年相同)
auto b = std::bind(&MenuItem);
NoncopyableObject obj(7);
b(obj); // compile error in VS 2010 SP1, OK in GCC
b(std::reference_wrapper<NoncopyableObject>(obj)); // OK in both
所以,即使不使用该参数,MS的bind()
也会复制其参数,而boost和GCC的bind()
根本不会对该参数感到烦恼。
通过将FUNC
typedef更改为
typedef boost::function1<void, std::tr1::reference_wrapper<NoncopyableObject> > FUNC;