C++ 使lambda不可复制/不可移动

C++ 使lambda不可复制/不可移动,c++,lambda,C++,Lambda,考虑以下几点: #包括 #包括 int main(){ 标准:螺纹t; const auto l=[x=std::move(t)]{}; decltype(l)m=std::move(l); } 此代码不使用以下消息编译: prog.cc:在函数“int main()”中: 程序cc:7:32:错误:使用已删除的函数“main():::(const main()::&)” 7 | decltype(l)m=std::move(l); |

考虑以下几点:

#包括
#包括
int main(){
标准:螺纹t;
const auto l=[x=std::move(t)]{};
decltype(l)m=std::move(l);
}
此代码不使用以下消息编译:

prog.cc:在函数“int main()”中:
程序cc:7:32:错误:使用已删除的函数“main():::(const main()::&)”
7 | decltype(l)m=std::move(l);
|                                ^
prog.cc:6:37:注意:“main()::(const main():::&)”被隐式删除,因为默认定义的格式不正确:
6 | const auto l=[x=std::move(t)]{;
|                                     ^
程序cc:6:37:错误:使用已删除的函数“std::thread::thread(const std::thread&)”
在prog.cc中包含的文件中:2:
/opt/wandbox/gcc-head/include/c++/10.0.1/thread:154:5:注意:此处声明
154 |线程(const thread&)=删除;
|     ^~~~~~

是否有一种方法可以使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>>;
NoCopyMove
是一个简单的mixin,用于禁用复制和移动。以这种方式编写它允许我们将
的专门化保持为简单的聚合

所有
Fixed
所做的都是继承/初始化它作为参数的函子(如果可能的话,可以保证复制省略)。然后公开它的
操作符()


由于没有涉及任何成员(除了
Functor
中的成员),并且由于lambda不可能从我们的自定义
NoCopyMove
类继承,因此空基优化开始用于无状态lambda。因此,对象不应比初始化它们时使用的lambda大

很好!它还将允许C+20引入的无状态lambda的默认构造?信息技术看起来应该添加默认的构造函数:
NoCopyMove()=default和BTW
=删除移动成员似乎足够了,因为不小心也删除了复制成员。@αλεχολΓτ-当然我检查过了。但这并不意味着我的编译器不会有bug。顺便说一句,我更喜欢显式删除内容,而不是隐式删除。@sweenish这是
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;
      |     ^~~~~~
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>>;
const auto l = Fixed{[]{}};