在简单地移动参数时使用函数模板参数的优点



考虑以下结构,它存储一个函数:

struct yyy {
std::function<int()> myFunc;
void set_func_1(std::function<int()>&& f) {
myFunc = std::move(f);
}
template<typename funcT>
void set_func_2(funcT&& f) {
myFunc = std::move(f);
}
};

根据这个答案,我知道使用模板参数允许编译器优化内容。

但是对于上面的结构,我直接移动函数来存储它,使用模板参数有什么好处吗?

&&

引用,即使拼写方式相同,也起着不同的作用。

void set_func_1(std::function<int()>&& f) {
myFunc = std::move(f);
}

是正确的,但只接受 r 值引用。在template<typename funcT> void set_func_2(funcT&& f)中,&&是一个转发引用,所以在正文中使用std::move(f)是错误的 - 它可能从非临时对象窃取状态。相反,您需要使用std::forward<funcT>(f).

与第一个函数相比,第二个函数的一个优点是不是优化。第一个只接受 r 值,例如function<int> f = []{return 1;}; struct yyy; yyy.set_func_2(f);不会编译。

编写set()方法的一个好的、简单的、接近最优的方法是按值传递并移动:

void set_func_3(std::function<int()> f) {
myFunc = std::move(f);
}

斯科特·迈耶斯(Scott Meyers(的《现代有效C++》一书中详细介绍了其适用性。

最新更新