是否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);
Run Code Online (Sandbox Code Playgroud)
猜猜哪个operator()被调用 - 采用右值参考的那个.它似乎是设计的.这种行为背后的理由是什么?
Bar*_*rry 10
是的,不是.是的,参数被转发.但是,不是,根据您在调用时提供的参数来完成重载解析 - 它是基于模板参数完成的std::function.
std::function<void(int)>意味着你有一个带有a的callable int,它隐含的是一个intrvalue.Widget使用rvalue类型调用会int优先于int&&重载过int const&载,这就是为什么选择该过载的原因.function一旦你选择了你想要的东西,你调用实际对象并不重要void(int)- 这是首选的重载.
实际的调用操作符的行为就像:
struct widget_function {
void operator()(int arg) const {
// ~~~~~ ~~~~
w_(std::forward<int>(arg));
// ~~~
}
Widget w_;
};
Run Code Online (Sandbox Code Playgroud)
带下划线的部分来自您提供的签名std::function.你可以看到两者f(x)并f(5)最终调用相同operator()的Widget.
简而言之,std::function<Sig>类型擦除满足的单个过载Sig.它不会键入擦除整个过载集.你要求void(int),所以你void(int)只得到void(int).