Reputation: 9090
Here, Wrapper::set
should be able to take any function or function object that matches the int(int)
signature, and store it into the std::function
. It should work with function pointers, lambdas, objects with operator()
, std::bind
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 set
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; }
Upvotes: 4
Views: 162
Reputation: 302757
The simplest version:
void set(std::function<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.
Upvotes: 6