trouble binding functions with boost

Started by
5 comments, last by swiftcoder 16 years, 8 months ago
Hello, I recently asked here how to use boost bind and boost function to help create an abstraction layer between my classes. The structure of my desing is as follows: class BaseClass {...}; class ObjectClass : public BaseClass { boost::function<BaseClass * (std::string)> _pfn_get; boost::function<BaseClass * (std::string, BaseClass *)> _pfn_create; ... }; SomeOtherManagerClass : public Singleton<SomeOtherManagerClass> { ... }; ManagerClass { ManagerClass() { SomeOtherManagerClass* pMgr = SomeOtherManagerClass::GetInstancePtr(); ObjectClass* ptr = new ObjectClass; ptr->_pfn_get = std::bind1st(std::mem_fun(&SomeOtherManagerClass::getData), pMgr); //this works fine ptr->_pfn_create = std::bind1st(std::mem_fun(&SomeOtherManagerClass::createData), pMgr); //this does not work } ... }; This does not seem to work... ptr->_pfn_create = std::bind1st(std::mem_fun(&SomeOtherManagerClass::createData), pMgr); //this does not work I tried: ptr->_pfn_create = boost::bind(&SomeOtherManagerClass::createData, pMgr); but had no luck. I keep getting compiler errors and in some cases causes VC8's compiler to crash. The only difference is that the second function takes two input params. What am i doing wrong?
Advertisement
I don't knwo what gives you troubles, but try giving a look to the boost/bind.hpp: I've just discovered it yesterday, so I'm not going to explain to you how to use it, but they say that it is easier than the stl version, and more powerful as well...
According to the boost::bind docs, you need "_1" at the end. Try "boost::bind(&SomeOtherManagerClass::createData, pMgr, _1);". I think that'll fix it.
To explain Mr. Grinch's advice more clearly:

When you give boost::bind a member function pointer as the first argument, the resultant bound function has an additional argument prepended: the object which the function is executed on. So if I had a member function Foo::Bar(int i), boost::bind(&Foo::Bar, a, b) would produce a functionoid which took a as a Foo& and b as an int. Therefore, a common thing to do is to partially apply the function (see docs) on only its first argument, binding a particular object: boost::bind(&Foo::Bar, myFoo, _1). The result of this is a unary function which calls Bar on myFoo.
Hmm that didn't quite fix my issues as I am still having troubles.

I am trying to assign the function object to the following boost::function objects

boost::function<BaseClass* (std::string)> _pfn_get;
boost::function<BaseClass* (std::string, BaseClass*)> _pfn_create;


The following works:
ptr->_pfn_get = boost::bind(&SomeOtherManagerClass::getData, pMgr, _1);

This does not:
ptr->_pfn_create = boost::bind(&SomeOtherManagerClass::createData, pMgr, _1);

The only difference is that getData takes one parameter and createData takes 2.

I get a compile error on the createData function.

1>f:\libraries\boost_1_34_0\boost\bind.hpp(66) : error C2825: 'F': must be a class or namespace when followed by '::'
1> f:\libraries\boost_1_34_0\boost\bind\bind_template.hpp(15) : see reference to class template instantiation 'boost::_bi::result_traits<R,F>' being compiled
1> with
1> [
1> R=boost::_bi::unspecified,
1> F=BaseClass *(__thiscall MyManager::* )(std::string,BaseClass *)
1> ]
1> f:\framework\mymanager.cpp(69) : see reference to class template instantiation 'boost::_bi::bind_t<R,F,L>' being compiled
1> with
1> [
1> R=boost::_bi::unspecified,
1> F=BaseClass *(__thiscall MyManager::* )(std::string,BaseClass *),
1> L=boost::_bi::list2<boost::_bi::value<MyManager *>,boost::arg<1>>
1> ]
1>f:\libraries\boost_1_34_0\boost\bind.hpp(66) : error C2039: 'result_type' : is not a member of '`global namespace''
1>f:\libraries\boost_1_34_0\boost\bind.hpp(66) : error C2146: syntax error : missing ';' before identifier 'type'
1>f:\libraries\boost_1_34_0\boost\bind.hpp(66) : error C2208: 'boost::_bi::type' : no members defined using this type
1>f:\libraries\boost_1_34_0\boost\bind.hpp(66) : fatal error C1903: unable to recover from previous error(s); stopping compilation




If createData() expects two arguments, then you need to bind two arguments (currently you're only binding one - the placeholder).

Perhaps you could post getData() and createData()? That might make it easier to see what's going wrong.
Quote:Original post by mooreaa
Hmm that didn't quite fix my issues as I am still having troubles.

I am trying to assign the function object to the following boost::function objects

boost::function<BaseClass* (std::string)> _pfn_get;
boost::function<BaseClass* (std::string, BaseClass*)> _pfn_create;


The following works:
ptr->_pfn_get = boost::bind(&SomeOtherManagerClass::getData, pMgr, _1);

This does not:
ptr->_pfn_create = boost::bind(&SomeOtherManagerClass::createData, pMgr, _1);

The only difference is that getData takes one parameter and createData takes 2.

I get a compile error on the createData function.

_1 and _2 don't specify the number of arguments, instead they bind the n'th argument. In your second example:

ptr->_pfn_create = boost::bind(&SomeOtherManagerClass::createData, pMgr, _1, _2);

You can do some really neat things with this, such as changing the order of arguments, or even duplicating or ignoring arguments:

ptr->_pfn_create = boost::bind(&SomeOtherManagerClass::createData, pMgr, _3, _1, _3);

(third argument is used twice, second argument is ignored)

Tristam MacDonald. Ex-BigTech Software Engineer. Future farmer. [https://trist.am]

This topic is closed to new replies.

Advertisement