Shoe
Shoe

Reputation: 76240

How can I detect parameter types of a function passed as a parameter?

Problem

I have to write a function that will be used as:

obj.transform([](x& a, y& b) { ... });
obj.transform([](x& a) { ... });
obj.transform([](y const& a, x& b, z const& c) { ... });
obj.transform([a, b](z const& c) { ... });
...

and inside the function declaration, I need to figure out the type of the arguments passed in.

The body of the function is then in the form (assuming x to be a member object and argfn the function passed in):

if (x.mfn1<std::remove_reference_t<Args>...>())
    argfn(x.mfn2<std::remove_reference_t<Args>>()...);

Context

If you are asking yourself, why and you have no idea how this could be useful, or if you think this is an XY problem, then you can find the context right here.

My attempts

Attempt #1

template<typename... Args>
void fn(std::function<void(Args...)>) { ... }

This doesn't work because there's apparently no way to have a conversion between that std::function and any lambda.

Attempt #2

template<typename... Args>
void fn(void(*)(Args...)) { ... }

This works with the first, second and third example above (prepending + on each lambda to force a conversion to pointer to function), but fails on the fourth.

Upvotes: 2

Views: 167

Answers (1)

Puppy
Puppy

Reputation: 146910

It's impossible. For example, what if the argument is a functor containing a templated (especially variadic) operator()? Or one that is overloaded? What are the "arguments" then?

The core problem here is that you're effectively re-implementing ranges but worse. Just offer plain iterators over the entities and then use std::transform. Or find a range library of your choice.

Upvotes: 1

Related Questions