Deduce type of lambda decayed to function pointer

So I've made this template to define functors inline:

template <typename F, F* f>
struct AsFunctor
{
    template <typename... Args>
    std::invoke_result_t<F, Args...> operator()(Args&&... args) { return f(std::forward<Args>(args)...); }
};

which can be used like so:

std::unique_ptr<char, AsFunctor<void(char*), +[](char* c) {/*STUFF*/}>> p;

Works great except that I have to needlessly declare the type of my function twice. Is there any way I can make the compiler deduce it? I've tried decltype in various ways such as

#define AS_FUNCTOR(lambda) AsFunctor<decltype(+lambda), +lambda>

but they're all compile errors as lambdas can't appear in an unevaluated context.

Upvotes: 0

Views: 111

Answers (1)

dan
dan

Reputation: 333

You can use auto for the functor and then use decltype to deduce the type.

template <auto F>
struct AsFunctor {
  template <typename... Args>
  std::invoke_result_t<decltype(F), Args...> operator()(Args&&... args) {
    return F(std::forward<Args>(args)...);
  }
};

int main() {
  int i;
  std::unique_ptr<char, AsFunctor<+[](char* c) { /*STUFF*/ }>> p;
}

I don't know the context, but generally you don't need any custom functor types (it's better to use templates right away, look at any example from the STL) or std::function.

Upvotes: 1

Related Questions