NoS*_*tAl 6 c++ templates auto c++17
我正在观看视频,其中Nicolai说自动失去移动语义为此示例:
template<typename Callable, typename... Args>
auto call(Callable&& op, Args&&... args) {
return std::invoke(std::forward<Callable>(op), std::forward<Args>(args)...);
}
Run Code Online (Sandbox Code Playgroud)
我在想:
这是为什么?
在这个例子中确实保证了 RVO的启动吗?如果是这样,有什么担心搬家的?
我认为Nicolai可能只是把它说得好一点.
返回时auto,函数返回一个值(将推导出的类型).如果std::invoke返回纯rvalue或xvalue,那么当然call会相应地构造结果(如果可能的话,通过移动).在这个意义上,我们不"失去移动语义".
但是当我们按值返回时,需要创建该值对象.它可以通过移动创建,并且在某些情况下(这里不存在)可以省略它,但必须创建它.保证副本省略不允许我们删除创建此对象.
如果std::invoke给我们一个xvalue(一个rvalue引用的东西),这可能是非常浪费的.我们为什么要构造一个返回它的对象?
这就是为什么一两张幻灯片后他说我们应该回来的原因decltype(auto).扣除规则将保留调用的值cateogry std::invoke:
如果它返回一个值,我们就不会变坏.我们自己call将返回一个值(它可以通过移动返回值来创建std::invoke).
如果std::invoke返回一个lvalue(X&)或一个xvalue(X&&),它将按原样返回,而不会通过复制或移动创建另一个对象.