tmlen tmlen - 4 months ago 18
C++ Question

Template argument for function type in C++


should be able to take any function or function object that matches the
signature, and store it into the
. It should work with function pointers, lambdas, objects with
expressions, etc.

#include <functional>

struct Wrapper {
using function_type = int(int);

std::function<function_type> func_;

template<typename Func> void set(Func func) { func_ = func; }

What would be the best form of
so that it works in all cases? I.e. one of

  • set(Func func) { func_ = func; }

  • set(Func&& func) { func_ = std::forward<Func>(func); }

  • set(Func& func) { func_ = func; }

  • set(const Func& func) { func_ = func; }


The simplest version:

void set(function_type f) {
    func_ = std::move(f);

The complex version:

template <class F,
    class = std::enable_if_t<std::is_assignable<std::function<function_type>&, F&&>::value>
void set(F&& f) {
    func_ = std::forward<F>(f);

There's no reason to do anything else. Both of these handle every case gracefully and correctly, the simple case has an extra move, which for std::function isn't an expensive operation, so I would strongly prefer the simple version unless you have a compelling, proven performance requirement to need the complex one.