C++中函数类型的模板参数

tml*_*len 4 c++ lambda templates c++11

在这里,Wrapper::set应该能够获取与int(int)签名匹配的任何函数或函数对象,并将其存储到std::function.它应该与函数指针,lambda,对象operator(),std::bind表达式等一起使用.

#include <functional>

struct Wrapper {
    using function_type = int(int);

    std::function<function_type> func_;

    template<typename Func> void set(Func func) { func_ = func; }
};
Run Code Online (Sandbox Code Playgroud)

什么是最好的形式,set以便它适用于所有情况?即其中之一

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

Bar*_*rry 6

最简单的版本:

void set(std::function<function_type> f) {
    func_ = std::move(f);
}
Run Code Online (Sandbox Code Playgroud)

复杂版本:

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);
}
Run Code Online (Sandbox Code Playgroud)

没有理由做任何其他事情.这两个都优雅而正确地处理每个案例,简单的情况有一个额外的移动,这std::function不是一个昂贵的操作,所以我强烈喜欢简单的版本,除非你有一个引人注目的,经过验证的性能要求需要复杂的.