否lambda是std::function
。 std::function
是一种类型的橡皮擦 - 它采用任何可破坏,可复制和可调用的签名,并擦除其余类型。
由于您的拉姆达无法复制,因此无法将其存储在std::function
中。
您可以使其成为可复制的(例如,通过将其状态存储在std::shared_ptr
中),也可以编写一个仅移动std::function
。
#include <utility>
#include <memory>
template<class Sig>class func;
namespace details{
template<class Sig>struct inner;
template<class R,class...Args>
struct inner<R(Args...)>{
virtual ~inner() {};
virtual R invoke(Args&&...args) =0;
};
template<class F,class Sig>struct impl;
template<class F,class R,class...Args>
struct impl<F,R(Args...)>:inner<R(Args...)>{
F f;
template<class... Ts>
impl(Ts&&...ts):f(std::forward<Ts>(ts)...){}
R invoke(Args&&...args)override{
return f(std::forward<Args>(args)...);
}
};
}
template<class T>struct emplace_as{};
template<class R,class...Args>
class func<R(Args...)>{
std::unique_ptr<details::inner<R(Args...)>> pImpl;
public:
R operator()(Args...args){
return pImpl->invoke(std::forward<Args>(args)...);
}
explicit operator bool()const{return pImpl;}
func(func&&)=default;
template<class F,class...Ts,class=typename std::enable_if<
std::is_convertible<decltype(std::declval<F>()(std::declval<Args>()...)),R>::value
>::type>
func(emplace_as<F>,Ts&&...ts):
pImpl(new details::impl<F, R(Args...)>{std::forward<Ts>(ts)...})
{}
template<class F,class=typename std::enable_if<
std::is_convertible<decltype(std::declval<F>()(std::declval<Args>()...)),R>::value
>::type>
func(F&&f):
func(
emplace_as<typename std::decay<F>::type>(),
std::forward<F>(f)
)
{}
};
或something like that。
(需要添加特点:右值参照该重载上()
,也许swap
,也许assign
和emplace
,也许类型定义为result_type
等),也许target
和target_type
)
一个lambda具有“不可告人”独特类型由编译器生成。你的问题是'std :: function'要求它的函数对象是'CopyConstructible','unique_ptr'不能被复制。 – 2014-10-11 22:16:04
但在例子中'lambda'是一个右值引用,它调用移动的构造函数。不是吗? – herolover 2014-10-11 22:22:33
没关系。 'std :: function'对于'CopyConstructible'使用的函数对象有很强的要求,而你的lambda不是因为它捕获了'unique_ptr'。故事结局。 – 2014-10-11 22:25:25