完美转发一个仿函数
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-qualifier,我应该做后一个版本吗?我应该关心我调用哪个重载吗?
谢谢!
完美转发在您要传递一个对象(可能是右值)给其他函数的情况下很有用,而您不确定它是否是右值或左值。在这种情况下,你只是使用 func
,所以转发它没有好处或坏处。
请记住,std::forward
是一个条件 std::move
,它只是对右值引用的转换。
此外,只有当您转发的内容有可能调用复制或移动构造函数时,它才真正有用。在许多情况下,const T&
就可以了。
编辑:
正如 berry 指出的那样, 如果 func
有 ref-qualified operator()
就很重要。我从未见过或使用过 ref 限定方法(据我所知。这种情况极为罕见。)更多信息请参见 Barry's answer。
它也会这样读:What is "rvalue reference for *this"?
struct C {
void operator()() && { std::cout << "rval\n"; }
void operator()() const & { std::cout << "lval\n"; }
};
callMe(C{});
由于 ref-qualified operator()
存在,第一个版本可能会做错事。考虑:
struct C {
void operator()() && { std::cout << "rval\n"; }
void operator()() const & { std::cout << "lval\n"; }
};
callMe(C{});
我给你一个右值 - 并希望看到 "rval"
- 但在第一个版本中,你总是将函数对象视为左值 - 所以我真的看到 "lval"
.
所以正确的解决方案是第二种 - forward
s func
也是如此。
在实践中,我不知道引用限定成员函数实际发生的频率,所以前者可能没问题。
我想知道使用完美转发函子的正确方法是什么?这是两个代码片段。哪个最好,如果都不是,最好的形式是什么?
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-qualifier,我应该做后一个版本吗?我应该关心我调用哪个重载吗?
谢谢!
完美转发在您要传递一个对象(可能是右值)给其他函数的情况下很有用,而您不确定它是否是右值或左值。在这种情况下,你只是使用 func
,所以转发它没有好处或坏处。
请记住,std::forward
是一个条件 std::move
,它只是对右值引用的转换。
此外,只有当您转发的内容有可能调用复制或移动构造函数时,它才真正有用。在许多情况下,const T&
就可以了。
编辑:
正如 berry 指出的那样, 如果 func
有 ref-qualified operator()
就很重要。我从未见过或使用过 ref 限定方法(据我所知。这种情况极为罕见。)更多信息请参见 Barry's answer。
它也会这样读:What is "rvalue reference for *this"?
struct C {
void operator()() && { std::cout << "rval\n"; }
void operator()() const & { std::cout << "lval\n"; }
};
callMe(C{});
由于 ref-qualified operator()
存在,第一个版本可能会做错事。考虑:
struct C {
void operator()() && { std::cout << "rval\n"; }
void operator()() const & { std::cout << "lval\n"; }
};
callMe(C{});
我给你一个右值 - 并希望看到 "rval"
- 但在第一个版本中,你总是将函数对象视为左值 - 所以我真的看到 "lval"
.
所以正确的解决方案是第二种 - forward
s func
也是如此。
在实践中,我不知道引用限定成员函数实际发生的频率,所以前者可能没问题。