Reputation: 3919
I have a problem with boost::function along with template functions. The scenario is as follows;
I want to run a function in another function called "setter". my function is something like
data.totalSize(TotalSize);
totalSize function input argument's type is "uint32_t" and output argument's type is "void".
So I decide to use boost::function; Below is my code:
setter(boost::bind(&myIDL::payload::totalSize,boost::ref(data),_1),(TotalSize));
and the setter implementation is
template<typename Outer>
inline void setter(boost::function<void(Outer)> myFunc, Outer myValue)
{
myFunc(myValue);
}
I will get the following compile error:
error: no matching function for call to setter(boost::_bi::bind_t<void, boost::_mfi::mf1<void,myIDL::payload, unsigned int>, boost::_bi::list2<boost::reference_wrapper<myIDL::payload>, boost::arg<1> > >, quint32&)'
It seems that boost::function does not understand my template type. So I decide to write it as below:
template<typename Outer>
inline void setter(boost::function<void(unit32_t)> myFunc, Outer myValue)
{
myFunc(myValue);
}
And it works! So I want to know how to solve my problem. Thanks in advance for your helps.
Best Regards, Reza
Upvotes: 1
Views: 210
Reputation: 48447
Template argument type deduction only deduces types, it doesn't consider any conversions.
Just like the compiler didn't fail to inform you, the result of boost::bind
yields a prvalue of some unspeakable type:
boost::_bi::bind_t<void, boost::_mfi::mf1<void,myIDL::payload
, unsigned int>
, boost::_bi::list2<boost::reference_wrapper<myIDL::payload>
, boost::arg<1> > >
which, clearly, is not the same as:
boost::function<void(Outer)>
That is, type template parameter Outer
cannot be deduced from the type of an argument expression. A solution is to accept any function object:
template <typename F, typename Outer>
inline void setter(F myFunc, Outer myValue)
{
myFunc(myValue);
}
or put Outer
in a non-deduced context (and pay the price of type-erasure):
#include <boost/mpl/identity.hpp>
inline void setter(boost::function<void(typename boost::mpl::identity<Outer>::type)> myFunc
, Outer myValue)
{
myFunc(myValue);
}
Upvotes: 2