用std::tr1::bind替换boost::bind出现问题

Problem replacing boost::bind with std::tr1::bind

本文关键字:bind 问题 boost 替换 tr1 std      更新时间:2023-10-16

我有以下代码,在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': cannot access private member in class 'boost::noncopyable_::noncopyable' .

这个诊断发生在编译器生成的函数'NoncopyableObject::NoncopyableObject(const NoncopyableObject &)'

它试图为NoncopyableObject生成一个复制构造函数。有人知道为什么会这样吗?MenuItemDispatcher的调用操作符接受对NoncopyableObject的引用,因此我正在努力查看出了什么问题。

这似乎是bind在MS Visual Studio(包括2010)和GNU gcc(我测试了4.4.1和4.5.2,两者都以您期望的方式工作)中实现的差异

考虑以下代码,给定您的定义

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类型定义更改为

来编译和运行(在2010年)。
typedef boost::function1<void, std::tr1::reference_wrapper<NoncopyableObject> > FUNC;