So in it's most distilled form I have something like this going on,
template <class T>
bool f(const T &a, const T &b, std::function<bool(const T&, const T&)> func)
{
return func(a,b);
}
template <class T>
bool g(const T &a, const T &b)
{
return true;
}
But any attempt to call f()
, with anything, f('a', 'b', g)
, f(1, 2, g)
, always results in "no matching function for call to 'f'", regardless of whether I pass the variables as const references or just plain values or whatever. I'm assuming it's failing to deduce some template, but I have no idea where or why.
I will admit, I have a very tenuous grasp on how to use function objects in general, is doing something like this even possible?
The parameter func
is declared as std::function
, and you're trying to pass a function pointer, which requires implicit conversion. Template argument deduction doesn't consider implicit conversion and then deduction fails.
Type deduction does not consider implicit conversions (other than type adjustments listed above): that's the job for overload resolution, which happens later.
You can construct an std::function
explicitly,
f('a', 'b', static_cast<std::function<bool(const char&, const char&)>>(g<char>));
Or specify the template argument explicitly (to bypass template argument deduction and make implicit conversion taking effect later),
f<char>('a', 'b', g<char>);
Or just don't use std::function
.
template <class T, class F>
bool f(const T &a, const T &b, F func)
{
return func(a,b);
}
f('a', 'b', g<char>);
I've fixed this up a bit for you and added some examples. This should help you to understand how to use a simple std::function.
#include <iostream>
#include <string>
#include <functional>
template <class T>
bool f(const T &a, const T &b, std::function<bool(const T&, const T&)> func)
{
return func(a,b);
}
template <class T>
bool g(const T &a, const T &b)
{
return a==b; // a simple comparator
}
int main()
{
int a = 1;
int b = 1;
// instantiate f and g as integer type functions
if( f<int>(a,b,g<int>) == true)
std::cout << "true" << std::endl;
else
std::cout << "false" << std::endl;
std::string c="dead";
std::string d="beef";
// and now as strings
if( f<std::string>(c,d,g<std::string>) == true)
std::cout << "true" << std::endl;
else
std::cout << "false" << std::endl;
return 0;
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With