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

发布于 2024-11-19 15:01:29 字数 1488 浏览 2 评论 0原文

我有以下代码,可以在 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 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

陪我终i 2024-11-26 15:01:29

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

考虑下面的代码,考虑到您的定义

auto b = boost::bind(&MenuItem);
NoncopyableObject obj(7);
b(obj);  // OK in VS and GCC

将 boost::bind 替换为 std::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 更改为来编译和运行您的示例(在 2010 年)

typedef boost::function1<void, std::tr1::reference_wrapper<NoncopyableObject> > FUNC;

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

auto b = boost::bind(&MenuItem);
NoncopyableObject obj(7);
b(obj);  // OK in VS and GCC

replacing boost::bind with std::bind (I'm using 2010, the error message appears to be the same as in your 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

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's bind() 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

typedef boost::function1<void, std::tr1::reference_wrapper<NoncopyableObject> > FUNC;
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文