为什么我可以将接受值的可调用对象传递给接受引用的 std::function?
Why can I pass a value-accepting callable to a reference-accepting std::function?
当我声明一个变量 function<void(const Foo&)>
时,编译器仍然让我分配一个接受值的 lambda:
function<void(const Foo&)> handler;
handler = [](Foo f){};
(参见 http://cpp.sh/5dsp)
所以当调用处理程序时,将制作一个副本。标准的哪一部分允许这样做?有没有一种方法可以标记客户端代码这将是一个问题(某些 static_assert 之类的?)?
根据 [func.wrap.func.con]
std::function<R(ArgTypes...)>
有一个
template<class F> function& operator=(F&& f);
加上以下备注:
This assignment operator shall not participate in overload resolution unless decay_t<F> is Lvalue-Callable for argument types ArgTypes... and return type R.
哪里
A callable type F is Lvalue-Callable for argument types ArgTypes and return type R if the expression INVOKE<R>(declval<F&>(), declval<ArgTypes>()...), considered as an unevaluated operand, is well formed.
因此您可以将任何可使用 ArgTypes...
调用的函数分配给 std::function<R(ArgTypes...)>
并返回可隐式转换为 R
.
的函数
我看不出如何避免将 std::function
包装在更有限的东西中。
当我声明一个变量 function<void(const Foo&)>
时,编译器仍然让我分配一个接受值的 lambda:
function<void(const Foo&)> handler;
handler = [](Foo f){};
(参见 http://cpp.sh/5dsp)
所以当调用处理程序时,将制作一个副本。标准的哪一部分允许这样做?有没有一种方法可以标记客户端代码这将是一个问题(某些 static_assert 之类的?)?
根据 [func.wrap.func.con]
std::function<R(ArgTypes...)>
有一个
template<class F> function& operator=(F&& f);
加上以下备注:
This assignment operator shall not participate in overload resolution unless decay_t<F> is Lvalue-Callable for argument types ArgTypes... and return type R.
哪里
A callable type F is Lvalue-Callable for argument types ArgTypes and return type R if the expression INVOKE<R>(declval<F&>(), declval<ArgTypes>()...), considered as an unevaluated operand, is well formed.
因此您可以将任何可使用 ArgTypes...
调用的函数分配给 std::function<R(ArgTypes...)>
并返回可隐式转换为 R
.
我看不出如何避免将 std::function
包装在更有限的东西中。