C ++ lambda具有已删除的复制赋值运算符。我不知道为什么。然而,这种限制可以很容易地解决。但我感觉不太好。以下方法可能有什么问题? Live code
template <class T> void assign(T& dest, T&& val) {
dest.~T();
new (&dest) T(std::forward<T>(val));
}
auto make_lambda(int i) {
return [v=std::make_shared<int>(i)] {std::cout << *v << "\n"; };
}
int main() {
auto one = make_lambda(1);
assign(one, make_lambda(2));
one(); // prints 2
}
我可以想到两个原因:
dest
主要部分仍然未初始化,并在主要部分再次被销毁。双删除。施工期间的例外情况也可以通过强有力的异常安全保障来解决。考虑assignv2
:
template <class T>
void assignv2(T& dest, const T& src)
{
static std::allocator<T> alloc;
static typename std::aligned_storage<sizeof(T), alignof(T)>::type storage;
std::memcpy(&storage, &dest, sizeof(T));
try {
new (&dest) T(src);
}
catch(...) {
std::memcpy(&dest, &storage, sizeof(T));
throw;
}
reinterpret_cast<T*>(&storage)->~T();
}
答案 0 :(得分:1)
您无需(复制/移动)分配lambda。
class lambda {
std::shared_ptr<int> v;
public:
explicit lambda(int i) : v(make_shared(i)) {}
void operator()() { std::cout << *v << "\n"; }
}
auto make_lambda(int i) {
return lambda(i);
}
或者,对于记忆案例,您不要更改memoise
:
template <typename Func>
auto memoized_recursion(Func func, Cache c = Cache::NO_RECLAIM)
{
static std::unordered_map<Func, decltype(memoise(func))> functor_map;
if(Cache::RECLAIM == c)
return functor_map.insert_or_assign(func, memoize(func)).first->second;
else
return functor_map.insert(func, memoize(func)).first->second;
}