3

I have a template function taking a std::function parameter, the template arguments defining function signature:

template<typename... Args>
void addController(const char * name, const std::function<bool(Args...)> & func);

It works passing a std::function variable:

std::function<bool()> foo_func = [this]()->bool {return this->isFoo(); };
addController<>("foo", foo_func);  //Works

But if I pass the lambda directly, it fails deducing the type:

//Fails to compile
addController<>("foo", [this]()->bool {return this->isFoo(); });

And using a non template function works:

void addControllerNoArg(const char * name, std::function<bool()> func);
addControllerNoArg("foo", [this]() {return this->isFoo(); });  //Works

I need the <typename... Args> template for unwrapping a variant vector argument tables into the function call. This actually does work in the implementation, the only issue is I can't pass a lambda to addController directly.

Minimal example: https://onlinegdb.com/MS1cEreKhk

4
  • template <typename FunctionType> void addControler(F f);. Don't confuse std::function to be the goto type whenever you need to pass around a callable. You need it for type erasure, ie when you need one object that can store all kinds of callables Commented Sep 28, 2022 at 11:59
  • I need <typename... Args> because internally, arguments are retrieved in a variant table that needs to be unwrapped into func call Commented Sep 28, 2022 at 12:04
  • 1
    Added a minimal example but there isn't more inside than what shown above Commented Sep 28, 2022 at 12:14
  • #includes and the context for this is a lot, when someone else wants to either reproduce your error or test their answer. Commented Sep 28, 2022 at 12:17

1 Answer 1

7

Way to go is generic callable:

template<typename F>
void addController(const char* name, F f)

You can forward it to your std::function version if needed:

template <typename... Args>
void addController(const char* name, const std::function<bool(Args...)> & func)
{
   /*..*/
}

template <typename F>
void addController(const char* name, F f)
{
    addController(name, std::function{f}); // CTAD used, so C++17 required
}
Sign up to request clarification or add additional context in comments.

4 Comments

Yeah overloads :)
I've tested this, but it says missing template arguments before {f} onlinegdb.com/3dSMUCSYvG
@galinette You need to compile with C++17 or newer.
@galinette That compiler doesn't seem to enable C++17 by default. It works here: godbolt.org/z/Y6G43fd9n

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.