(following on from C++ Guru Question)
There are a few reasons why the code before didn’t work: mainly
a) C++ template argument deduction works one-way with a list of candidates, it’s not H-M type inference.
b) A C++ lambda is a thing with some internal type, not a std::function (although it can be assigned to one, that doesn’t matter for template type deduction).
Anyway, a reasonable solution to this problem is to simplify the template argument matching to the function type, and use a simple function_traits template to take apart the function argument and return types.
template
struct function_traits
: public function_traits
{};
template
struct function_traits
{
typedef R returnType;
typedef A argType;
};
template
struct function_traits
: public function_traits
{};
template
struct Foo
{
T m_t;
};
template
typename function_traits::returnType operator/=(
Foo::argType> foo, const F& fn)
{
return fn(foo.m_t);
}
void mystery()
{
auto foo = Foo{1};
// this works...
function(int)> f1 = [] (int i) { return Foo{i}; };
auto bar1 = foo /= f1;
// this does too!
auto f2 = [] (int i) { return Foo{i}; };
auto bar2 = foo /= f2;
}