完美转发函子
Perfect forwarding a functor
我想知道使用完美转发函子的正确方法是什么?下面是两个代码片段。哪一个是最好的,如果两者都不是,最好的形式是什么?
template<typename T, typename... Args>
void callMe(T&& func, Args&&... args) {
func(std::forward<Args>(args)...);
}
或
template<typename T, typename... Args>
void callMe(T&& func, Args&&... args) {
std::forward<T>(func)(std::forward<Args>(args)...);
}
编辑:
它会影响过载解决吗?如果func
的operator()
有&&
或const &
的引用限定符,我应该做后一个版本,我应该关心我调用哪个重载吗?
谢谢!
由于存在 ref-qualified operator()
,第一个版本可能会做错事。考虑:
struct C {
void operator()() && { std::cout << "rvaln"; }
void operator()() const & { std::cout << "lvaln"; }
};
callMe(C{});
我给你一个右值 - 并希望看到"rval"
- 但在第一个版本中,你总是将函数对象视为左值 - 所以我真的看到了"lval"
.
因此,正确的解决方案是第二个 - 这也是forward
func
。
在实践中,我不知道 ref 限定成员函数实际发生的频率,因此前者可能没问题。
当您要将对象(可能是右值)传递给其他函数并且您不确定它是右值还是左值的情况下,完美转发很有用。在这种情况下,您只需使用 func
,因此转发它没有任何好处或坏处。
请记住,std::forward
是一个条件std::move
,它只是对 r 值引用的强制转换。
此外,它实际上仅在有可能为您转发的内容调用复制或移动构造函数时才有用。在许多情况下,const T&
会做得很好。
编辑:
正如贝瑞指出的那样,func
是否具有参考资格operator()
确实很重要。我从未见过或使用过 ref 限定的方法(据我所知。这是非常罕见的。更多在巴里的回答中。
它也会读到这个:什么是"*这个的右值参考"?
struct C {
void operator()() && { std::cout << "rvaln"; }
void operator()() const & { std::cout << "lvaln"; }
};
callMe(C{});
相关文章:
- 将函数参数完美转发到函数指针:按值传递呢?
- C++20理念:要求表达和完美转发
- 完美的转发和构造函数
- 我可以列表初始化 std::vector 并完美转发元素吗?
- 返回值的完美转发?
- 使用衰减与完美转发
- 可变参数模板:将整数参数完美转发到 lambda
- 完美转发C++重载和模板化函子及其参数
- 在完美转发中需要衰减
- C++完美转发:如何避免悬空引用
- 完美的对象转发阵列
- 无法理解一段具有完美转发和省略号的C++代码
- 在编写包装现有函数并检查错误的模板函数时,如何使用完美转发?
- 完美转发可变参数模板模板
- 在完美转发函数中公开参数类型,避免代码重复
- 完美的转发构造函数和已删除的构造函数
- 完美的转发功能推断出冲突错误
- 使用完美转发的模板转换构造函数
- 完美转发使用结构化绑定声明的变量
- 完美转发常量参数以进行持续评估