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.
This appears to be a difference in how
bindis 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
FUNCtypedef to