考虑以下代码:
#include <iostream>
#include <thread>
int main() {
std::thread t;
const auto l = [x = std::move(t)]{};
decltype(l) m = std::move(l);
}
Run Code Online (Sandbox Code Playgroud)
此代码不会编译为以下消息:
Run Code Online (Sandbox Code Playgroud)prog.cc: In function 'int main()': prog.cc:7:32: error: use of deleted function 'main()::<lambda()>::<lambda>(const main()::<lambda()>&)' 7 | decltype(l) m = std::move(l); | ^ prog.cc:6:37: note: 'main()::<lambda()>::<lambda>(const main()::<lambda()>&)' is implicitly deleted because the default definition would be ill-formed: 6 | const auto l = [x = std::move(t)]{}; | ^ prog.cc:6:37: error: use of deleted function 'std::thread::thread(const std::thread&)' In file included from prog.cc:2: /opt/wandbox/gcc-head/include/c++/10.0.1/thread:154:5: note: declared here 154 | thread(const thread&) = delete; | ^~~~~~
有没有办法使 lambda 不可复制或不可移动而无需显式捕获任何不可复制的变量(即[]留空)?
您可以编写一个简单的包络聚合来防止移动和复制。
struct NoCopyMove {
NoCopyMove(NoCopyMove const&) = delete;
NoCopyMove(NoCopyMove&&) = delete;
void operator=(NoCopyMove const&) = delete;
void operator=(NoCopyMove&&) = delete;
};
template<class Functor>
struct Fixed : Functor, NoCopyMove {
using Functor::operator();
};
template<typename F>
Fixed (F&&) -> Fixed<std::decay_t<F>>;
Run Code Online (Sandbox Code Playgroud)
像这样使用
const auto l = Fixed{[]{}};
Run Code Online (Sandbox Code Playgroud)
NoCopyMove是一个简单的 mixin,它禁止复制和移动。以这种方式编写它允许我们保持Fixed作为简单聚合的特化。
Fixed所做的一切都是继承/初始化为基础(在可能的情况下保证复制省略)它作为参数给出的函子。然后暴露其operator().
由于没有涉及成员(除了可能在 中Functor),并且由于 lambda 不可能从我们的自定义NoCopyMove类继承,因此空基优化开始用于无状态 lambda。所以对象不会比你初始化它们的 lambda 大。
| 归档时间: |
|
| 查看次数: |
118 次 |
| 最近记录: |