草庐IT

c++ - 为什么隐式和显式删除的 move 构造函数会受到不同对待?

C++11标准中隐式和显式删除move构造函数的不同处理背后的基本原理是什么,关于move构造函数的隐式生成包含/继承类?C++14/C++17有什么改变吗?(C++14中的DR1402除外)注意:我明白发生了什么,我明白这是根据C++11标准的规则,我对这些暗示这种行为的规则的基本原理感兴趣(请确保不要简单地重申它是这样的,因为标准是这样说的)。假设一个类ExplicitDelete带有一个显式删除的move构造函数和一个显式默认的复制构造函数。这个类不是moveconstructible即使有一个兼容的复制构造函数可用,因为重载决策选择了move构造函数并且由于它被删除而在编译时失

c++ - move 语义和虚拟方法

在C++11中,我们在某些情况下被引导通过值传递对象,在其他情况下通过常量引用。但是,该指南取决于实现的方法,而不仅仅是它的接口(interface)和它的客户的预期用途。当我写一个接口(interface)时,我不知道它将如何实现。编写方法签名有什么好的经验法则吗?例如-在下面的代码片段中,我应该使用Bar1或Bar2?classIFoo{public:virtualvoidBar1(std::strings)=0;virtualvoidBar2(conststd::string&s)=0;};如果您同意正确的签名取决于实现,则可以停止阅读此处。这是一个例子,说明了我为什么这么相信。

c++ - 接收参数并为可能失败的函数 move 语义(强大的异常安全性)

我有一个函数可以对作为接收器参数传入的大量数据进行操作。我的BigData类型已经支持C++11,并带有功能齐全的move构造函数和move赋值实现,因此我无需复制该死的东西就可以逃脱:ResultprocessBigData(BigData);[...]BigDatab=retrieveData();Resultr=processBigData(std::move(b));这一切都很好。但是,我的处理功能可能会在运行时偶尔失败,从而导致异常。这不是真正的问题,因为我可以修复问题并重试:BigDatab=retrieveData();Resultr;try{r=processBigDa

c++ - 有没有办法将 std::move std::string 放入 std::stringstream

在c++引用中,我没有看到std::stringstream构造函数接受std::string的右值引用。是否有任何其他帮助函数可以在没有开销的情况下将字符串move到stringstream,或者在进行这种限制的背后是否有特殊原因? 最佳答案 从C++20开始,您可以将stringmove到stringstream中:cppreferenceC++20之前的旧答案:Idonotseeastd::stringstreamconstructoracceptingrvaluereferenceofstd::string没错。即使是str

c++ - 传递值导致额外 move

我正在尝试理解move语义和复制/move省略。我想要一个包含一些数据的类。我想在构造函数中传递数据,我想拥有这些数据。看完this,this和this我的印象是,在C++11中,如果我想存储一个拷贝,那么按值传递应该至少与任何其他选项一样有效(除了增加代码大小的小问题)。然后如果调用代码想避免复制,它可以通过传递右值而不是左值来实现。(例如使用std::move)所以我试了一下:#includestructData{Data(){std::cout输出:1.DataWrapperWithMove:constructormoveconstructor2.DataWrapperByVal

c++ - 是否保证在返回时 move 临时对象的子对象?

#include#includeusingnamespacestd;autof(){vectorcoll{"hello"};////MustIusemove(coll[0])?//returncoll[0];}intmain(){autos=f();DoSomething(s);}我知道:如果我只是returncoll;,那么coll肯定会在返回时move。但是,我不确定:coll[0]是否也保证在返回时move?更新:#includestructA{A(){std::coutgcc6.2和clang3.8输出相同:constructedcopy-constructeddestruct

c++ - 复制/move 省略需要复制/move 构造函数的显式定义

考虑以下程序:#include#includeclassT{public:T(){printf("addressatconstruction:%zx\n",(uintptr_t)this);}//T(constT&){printf("copy-constructed\n");}//helps//T(T&&){printf("move-constructed\n");}//helps//T(constT&)=default;//doesnothelp//T(T&&)=default;//doesnothelp};Tf(){returnT();}intmain(){Tx=f();print

c++ - 将其 move 到 map 后访问一对

如果我将一对move到映射中,但由于键已经存在而导致插入失败,我可以在之后安全地使用该对吗?//objectsavailable:map,pairautoinsert_pair=map.insert(std::move(pair));if(!insert_pair.second){//canIsafelyaccesspairhere?}这是否记录在标准中? 最佳答案 鉴于规范的当前状态,您不能对函数调用返回后参数的状态做出任何假设,这看起来多么荒谬(请阅读下文)。要了解原因,我们首先要指出insert()成员函数是根据emplace

c++ - 为什么 std::map 的 move 构造函数不是 noexcept?

正如cppreference.com所说,Mapsareusuallyimplementedasred-blacktrees.所以move一个std::map只是将指针move到根节点+其他信息如大小。为什么std::map的move构造函数没有标记为noexcept? 最佳答案 这是因为我无法说服所有的实现者进入可以放入map的无资源状态。例如,一个实现需要有一个端节点指向,即使在默认构造状态下也是如此。允许(但不是必需)实现将该端节点放在堆上。Amoved-frommapmustbeinavalidstate.IE。当end()

c++ - "Extending move semantics to *this"是什么意思?

拜托,有人可以用简单的英语解释什么是“Extendingmovesemanticsto*this”吗?Iamreferringtothisproposal.我要寻找的只是什么是什么以及为什么我们需要它。请注意,我确实理解一般的右值引用是什么,move语义是建立在它之上的。我无法理解这样的扩展添加到右值引用的内容! 最佳答案 ref-qualifier特性(指示*this的类型)将允许您区分成员函数是否可以在右值或左值(或两者)上调用,并根据那。firstversion在非正式部分给出了一些理由:Preventsurprises:st