gpt4 book ai didi

c++ - 复制分配相同类型的 C++ lambda

转载 作者:行者123 更新时间:2023-11-30 05:10:25 25 4
gpt4 key购买 nike

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
}

我能想到的可能有两个原因:

  1. 构造可能会抛出并且 dest main 保持未初始化并稍后在 main 中再次销毁。双重删除。
  2. 如果一些写得不好的库在析构函数中抛出,析构函数可能会抛出异常。

构造过程中的异常也可以通过强大的异常安全保证来解决。考虑 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();
}

最佳答案

您不需要能够(复制/移动)分配 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;
}

关于c++ - 复制分配相同类型的 C++ lambda,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45696470/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com