[function,bind] Templated function<> function
Ok, the subject-line might be a bit confusing. :-)
I have the following template function:
template<class T>
bool is(const string& str);
Its implementation is not important. It checks if a string can be converted
to type T by std::stringstream. I also have the following function:
template <class T>
function
AMDG Michiel Helvensteijn wrote:
Ok, the subject-line might be a bit confusing. :-)
I have the following template function:
template<class T> bool is(const string& str);
Its implementation is not important. It checks if a string can be converted to type T by std::stringstream. I also have the following function:
template <class T> function
neg(function func) { return !bind(func, _1); } Which I use in the following way:
BOOST_CHECK_PREDICATE( neg(is<int>), ("text") );
But the compiler (GCC 4.1.2) complains:
error: no matching function for call to 'neg(<unresolved overloaded function type>)'
What's the problem. And, also, what's the solution? :-)
Internal to the compiler, the type of is<int> is a special type used to
flag overloads. (unresolved overloaded function type). The problem is
that you are passing this special type to a function template (the
boost::function constructor) which does not provide enough information
to resolve the overloading. The solution is to add a cast:
static_cast
Steven Watanabe wrote:
But the compiler (GCC 4.1.2) complains:
error: no matching function for call to 'neg(<unresolved overloaded function type>)'
What's the problem. And, also, what's the solution? :-)
Internal to the compiler, the type of is<int> is a special type used to flag overloads. (unresolved overloaded function type). The problem is that you are passing this special type to a function template (the boost::function constructor) which does not provide enough information to resolve the overloading.
Maybe I misunderstand your explanation. But I'm not sure if is<int> has anything to do with the problem. As a test I tried the following: bool foo(int a) { return a == 1; } ... BOOST_CHECK_PREDICATE( neg(foo), (2) ); Which gives a similar (though less unresolved) error-message: error: no matching function for call to 'neg(bool (&)(int))'
The solution is to add a cast: static_cast
Hm. That's not exactly pretty. I'd rather use boost::bind itself on the call site. I was hoping to be able to fix something in the definition of neg instead. -- Michiel Helvensteijn
AMDG Michiel Helvensteijn wrote:
BOOST_CHECK_PREDICATE( neg(foo), (2) );
Which gives a similar (though less unresolved) error-message:
error: no matching function for call to 'neg(bool (&)(int))'
neg(&foo) might work better.
The solution is to add a cast: static_cast
Hm. That's not exactly pretty. I'd rather use boost::bind itself on the call site. I was hoping to be able to fix something in the definition of neg instead.
Does it work if you make the argument to neg bool (*f)(const std::string&)? In Christ, Steven Watanabe
Steven Watanabe wrote:
Which gives a similar (though less unresolved) error-message:
error: no matching function for call to 'neg(bool (&)(int))'
neg(&foo) might work better.
I tried that too. The error is: error: no matching function for call to 'neg(bool (*)(int))'
Hm. That's not exactly pretty. I'd rather use boost::bind itself on the call site. I was hoping to be able to fix something in the definition of neg instead.
Does it work if you make the argument to neg bool (*f)(const std::string&)?
Yes. Both:
function
AMDG Michiel Helvensteijn wrote:
But you understand why I'd like the templated version to work. I have other predicates to test
Ok. The compiler can't deduce T in
template <class T>
function
Steven Watanabe wrote:
But you understand why I'd like the templated version to work. I have other predicates to test
Ok. The compiler can't deduce T in
template <class T> function
neg(function func); unless the argument is already a boost::function. No implicit conversions allowed.
I suspected it was too much to ask for. But I didn't know any alternative.
template<class F> struct not_t { typedef bool result_type; template<class T> bool operator()(const T& t) { return(!f(t)); } F f; };
template<class F> not_t<F> neg(F f) { not_t<F> result = { f }; return(result); }
This works as expected! So it's a function object, huh. I haven't used those before. I changed your solution in two small ways: * I removed the unused typedef. * I added some overloads of operator() to handle multiple parameters. This is a useful feature to have. Thanks for your help! -- Michiel Helvensteijn
participants (2)
-
Michiel Helvensteijn
-
Steven Watanabe