为什么我可以将接受值的callable传递给接受引用的std :: function?

时间:2017-09-15 11:17:18

标签: c++ covariance coercion function-object

当我声明变量function<void(const Foo&)>时,编译器仍然允许我分配一个接受值的lambda:

function<void(const Foo&)> handler;
handler = [](Foo f){};

(cfr。也http://cpp.sh/5dsp

因此,当调用处理程序时,将创建一个副本。标准的哪个部分允许这个?有没有办法我可以标记客户端代码,这将是一个问题(一些static_assert的排序?)?

1 个答案:

答案 0 :(得分:5)

按[ func.wrap.func.con ]

std::function<R(ArgTypes...)>

有一个

template<class F> function& operator=(F&& f);

带有以下说明:

  

除非decay_t&lt; F&gt;,否则该赋值运算符不应参与重载决策。对于参数类型ArgTypes是Lvalue-Callable,并返回类型R.

,其中

  

可调用类型F对于参数类型ArgTypes是Lvalue-Callable,如果表达式INVOKE&lt; R&gt;(declval&lt; F&amp;&gt;(),declval&lt; ArgTypes&gt;()...),则返回类型R,被认为是未经评估的操作数,形成良好。

因此,您可以使用std::function<R(ArgTypes...)>分配给ArgTypes...任何可调用的函数,并返回隐式转换为R的内容。

我不知道如何防止将std::function包裹在更有限的范围内。