0

I have a function template which takes a T&, this function is supposed to be supplied with a std::invocable<T&,const Foo&>.

The invocable is itself a template function and I want to deduce it's T with the already supplied object from the parameter list.

#include <concepts>

struct Foo {

};

template<typename T>
void baz(T& t, const Foo&) {

}
template<typename T, std::invocable<T&,const Foo&> Func>
void bar(T& obj,Func f ) {
    Foo foo{};
    f(obj,foo);
}

int main() {

    int a{0};

    bar(a,baz); // baz is meant to be baz<int>(int&,const Foo&), because a is int
    //bar(a,baz<int>);// works
}

Godbolt link

How can I do that?

Raildex
  • 3,406
  • 1
  • 18
  • 42
  • It's probably easier to use `std::function` – πάντα ῥεῖ Apr 16 '23 at 11:27
  • @πάνταῥεῖ Even with `std::function` this cannot automatically determine the template parameter to use for `baz`. The only thing that seems to be capable of this is the use of a function pointer in the signature of `bar`: https://godbolt.org/z/zT1aqP74a – fabian Apr 16 '23 at 11:44
  • You can wrap it in a lambda: https://godbolt.org/z/1PK6K38Eo – Artyer Apr 16 '23 at 14:52

1 Answers1

0

This can only work if f is specified to be a function pointer or reference (instead of just some constrained generic type). Otherwise there will be no attempt of overload resolution to do template argument deduction on baz.

template<typename T>
void bar(T& obj, void(*f)(T&, const Foo&)>)

If you still want to be able to invoke the function with other callables than functions with the exact same signature, then you can can still use your original overload in addition to this new one and let both forward to a common implementation.

user17732522
  • 53,019
  • 2
  • 56
  • 105