std::function
是否支持完美转发参数?我决定测试一下:
struct Widget
{
void operator()(int const&)
{
std::cout << "lvalue";
}
void operator()(int&&)
{
std::cout << "rvalue";
}
};
std::function<void(int)> f{Widget()};
int x = 5;
f(x);
猜猜哪个operator()
被调用 - 一个采用右值参考的人。它似乎是设计的。这种行为背后的理由是什么?
答案 0 :(得分:10)
是和否。是的,参数被转发。但是,不会,根据您在调用时提供的参数来完成重载解析 - 它是基于std::function
的模板参数完成的。
std::function<void(int)>
表示您有一个可调用的int
,其隐式为int
rvalue。使用Widget
类型的左值调用int
会优先int&&
超过int const&
重载,这就是选择该值的原因。一旦您选择了想要function
的对象,那么调用实际的void(int)
对象并不重要 - 这是首选的重载。
实际的调用操作符的行为就像:
struct widget_function {
void operator()(int arg) const {
// ~~~~~ ~~~~
w_(std::forward<int>(arg));
// ~~~
}
Widget w_;
};
带下划线的部分来自您提供给std::function
的签名。您可以看到f(x)
和f(5)
最终都会从operator()
调用相同的Widget
。
简而言之,std::function<Sig>
类型会删除满足Sig
的单个重载。它不会键入擦除整个过载集。您要求void(int)
,因此您获得了void(int)
且只有void(int)
。