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

xto*_*ofl 6 c++ covariance coercion function-object

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

function<void(const Foo&)> handler;
handler = [](Foo f){};
Run Code Online (Sandbox Code Playgroud)

(cfr.也是http://cpp.sh/5dsp)

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

Mar*_*ark 5

Per [ func.wrap.func.con ]

std::function<R(ArgTypes...)>
Run Code Online (Sandbox Code Playgroud)

有个

template<class F> function& operator=(F&& f);
Run Code Online (Sandbox Code Playgroud)

有以下说法:

除非decay_t <F>对于参数类型ArgTypes具有Lvalue-Callable并且返回类型R,否则此赋值运算符不应参与重载决策.

哪里

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

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

我不知道如何防止这种短缺包装std::function在一个更有限的东西.