用 std::tr1::bind 替换 boost::bind 时出现问题
我有以下代码,可以在 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,因此我很难看出出了什么问题。
I have the following code which compiles and runs fine under 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);
}
If I change the boost::bind to std::tr1::bind in main(), I get an error:
error C2248:
'boost::noncopyable_::noncopyable::noncopyable'
: cannot access private member declared in class'boost::noncopyable_::noncopyable'
.This diagnostic occurred in the compiler generated function
'NoncopyableObject::NoncopyableObject(const NoncopyableObject &)'
So it's trying to generate a copy constructor for NoncopyableObject. Anyone know why this might be so please? MenuItemDispatcher's call operator takes a reference to a NoncopyableObject, so I am struggling to see what's going wrong.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
这似乎是 MS Visual Studio(包括 2010)和 GNU gcc 中实现
bind
的方式不同(我测试了 4.4.1 和 4.5.2,两者都按照您期望的方式工作)考虑下面的代码,考虑到您的定义
将 boost::bind 替换为 std::bind (我使用的是 2010,错误消息似乎与 2008 中的相同)
所以,会发生什么MS 的
bind()
会复制其参数,即使该参数不会被使用,而 boost 和 GCC 的bind()
根本不关心该参数。我能够通过将
FUNC
typedef 更改为来编译和运行您的示例(在 2010 年)This appears to be a difference in how
bind
is implemented in MS Visual Studio (including 2010) and GNU gcc (I tested 4.4.1 and 4.5.2, both of which work the way you expected)Consider the following code, given your definitions
replacing boost::bind with std::bind (I'm using 2010, the error message appears to be the same as in your 2008)
So, what happens is that MS's
bind()
makes a copy of its argument even if the argument is not going to be used, while boost's and GCC'sbind()
does not bother with that argument at all.I was able to get your example to compile and run (on 2010) by changing the
FUNC
typedef to