标签: move-constructor

为什么不调用移动构造函数?

我正在使用C++ Primer第5版进行练习,如下所示:

练习13.50:将print语句放在String类的移动操作中, 并从第13.6.1节(第534页)中的练习13.48重新运行程序,该练习使用向量来查看何时避免复制.(P.544)

String是一个练习的类,其行为类似于std::string不使用任何模板.该String.h文件中:

class String
{
public:
    //! default constructor
    String();

    //! constructor taking C-style string i.e. a char array terminated with'\0'.
    explicit String(const char * const c);

    //! copy constructor
    explicit String(const String& s);

    //! move constructor    
    String(String&& s) noexcept;

    //! operator =
    String& operator = (const String& rhs);

    //! move operator =     
    String& operator = (String&& rhs) noexcept;

    //! destructor
    ~String();

    //! members
    char* …
Run Code Online (Sandbox Code Playgroud)

c++ constructor stl move-constructor c++11

9
推荐指数
1
解决办法
559
查看次数

如何返回没有复制构造函数的对象

我的问题涉及如何返回没有复制构造函数的对象.举一个例子,让我们想象一下,我有一些bigResource位于堆中,让我们说我用它来跟踪它unique_ptr.现在假设我将此资源的所有权交给了毛毛虫.然后我有一个CaterpillarWithBigResource.现在在某些时候,这CaterpillarWithBigResource将变成一个ButterflyWithBigResource,所以Caterpillar对象必须将所有权转移到Butterfly对象.

我编写了以下代码来模拟情况:

#include <cstdlib>
#include <iostream>
#include <memory>

class ButterflyWithBigResource {
public:

    //    If I uncomment just this line, I get an error
    //    ButterflyWithBigResource(const ButterflyWithBigResource& other) = default;

    //    If I uncomment just this line, I get an error
    //    ButterflyWithBigResource(const ButterflyWithBigResource& other) = delete;

    //   With both above lines commented out, I get no errors, and the program runs fine.

    ButterflyWithBigResource(std::unique_ptr<int>&& bigResource) :
    bigResource(std::move(bigResource)) …
Run Code Online (Sandbox Code Playgroud)

c++ copy-constructor move-constructor move-semantics c++11

9
推荐指数
1
解决办法
3244
查看次数

为什么调用此复制构造函数而不是移动构造函数?

下面的代码片段会调用复制构造函数,我希望调用移动构造函数:

#include <cstdio>

struct Foo
{
    Foo() { puts("Foo gets built!"); }
    Foo(const Foo& foo) { puts("Foo gets copied!"); }
    Foo(Foo&& foo) { puts("Foo gets moved!"); }
};

struct Bar { Foo foo; };
Bar Meow() { Bar bar; return bar; }
int main() { Bar bar(Meow()); }
Run Code Online (Sandbox Code Playgroud)

在VS11 Beta上,在调试模式下,打印:

Foo gets built!
Foo gets copied!
Foo gets copied!
Run Code Online (Sandbox Code Playgroud)

我检查了标准,并且Bar似乎满足了自动生成默认移动构造函数的所有要求,但这似乎不会发生,除非有另一个原因导致无法移动对象.我在这里看到了很多移动和复制构造函数相关的问题,但我认为没有人遇到过这个具体问题.

关于这里发生了什么的任何指示?这是标准行为吗?

c++ copy-constructor visual-c++ move-constructor c++11

8
推荐指数
1
解决办法
937
查看次数

在C++ 11中移出std priority_queue的元素

最小的工作示例.

#include <cassert>
#include <list>
#include <queue>
//#define USE_PQ

struct MyClass
{
    const char* str;
    MyClass(const char* _str) : str(_str) {}
    MyClass(MyClass&& src) { str = src.str; src.str = nullptr; }
    MyClass(const MyClass&) = delete;
};

struct cmp_func
{
    bool operator() (const MyClass&, const MyClass&) const
    {
        return true;
    }
};

typedef std::priority_queue<MyClass, std::vector<MyClass>, cmp_func> pq_type;

#ifdef USE_PQ
MyClass remove_front(pq_type& l)
{
    MyClass moved = std::move(l.top());
    // error from the above line:
    // use of deleted function ‘MyClass::MyClass(const MyClass&)’
    l.pop(); …
Run Code Online (Sandbox Code Playgroud)

c++ move-constructor move-semantics c++11

8
推荐指数
4
解决办法
4163
查看次数

是否可以在main中选择构造函数而无需编写复制构造函数?

真实的例子显然要长得多,但这总结了我的问题:

class Object
{
 int mInt1,mInt2;
 Object::Object();
 Object::Object(int param1);
 Object::Object(int param1, int param2);
};
Object::Object(){}
Object::Object(int param1):mInt1(param1){}
Object::Object(int param1, int param2):mInt1(param1),mInt1(param2){}
Run Code Online (Sandbox Code Playgroud)

然后在主要:

if (type1){
  Object instance(param1);
}
else{
  Object instance(param1,param2);
}
// do stuff with instance
Run Code Online (Sandbox Code Playgroud)

哎呦!这不起作用,实例超出了后续程序的范围.

Object instance;
if (type1){
  instance = Object(param1);
}
else{
  instance = Object(param1,param2);
}
// do stuff with instance
Run Code Online (Sandbox Code Playgroud)

但是现在我遇到了麻烦,因为我没有定义复制构造函数.我真的不想写一个拷贝构造函数,因为我的实际类有几十个成员,其中许多是非基本类型,可能需要更多的工作来复制.

具体来说,我得到了

main.cpp: error: use of deleted function ‘Object& Object::operator=(Object&&)’
         instance = Object(param1);
                  ^
note: ‘Object& Object::operator=(Object&&)’ is implicitly deleted because the default definition would …
Run Code Online (Sandbox Code Playgroud)

c++ scope copy-constructor move-constructor c++11

8
推荐指数
2
解决办法
386
查看次数

没有std :: move的Rvalue引用

我有下课

class widget {
// The methods only print their name, i.e. c'tor, destructor etc.
public:
    widget();
    widget(const widget&);
    widget(widget&&);
    ~widget();
    auto operator=(const widget&)  -> widget&;
    auto operator=(widget&&) -> widget&;
};
Run Code Online (Sandbox Code Playgroud)

我在下面的代码中使用它

#include "widget.h"

auto main() -> int {

    widget c(std::move(widget()));
    c = std::move(widget());

    return 0;
};
Run Code Online (Sandbox Code Playgroud)

由此产生的行为对我来说是可以理解的.在第一次调用中构造一个小部件,然后调用移动构造函数并在临时小部件上调用析构函数.

第二个调用也是这样,期望调用移动赋值运算符而不是移动构造函数.离开main方法,调用析构函数c.


现在有趣的是:

#include "widget.h"

auto main() -> int {

    widget c((widget()));
    c = widget();

    return 0;
};
Run Code Online (Sandbox Code Playgroud)

如果我省略了调用std::move,第一个案例就会停止工作并导致只有一个构造函数调用.而第二个案件仍然像以前一样工作.

我在这里错过了什么?为什么这两个函数调用对待它们的参数有所不同?我在gcc和clang上尝试过这个.

c++ move rvalue-reference move-constructor c++11

8
推荐指数
1
解决办法
613
查看次数

msvc / permissive- std :: string重载运算符'='不明确

与一起编译,/permissive但与一起失败/permissive-。什么不符合以及如何解决?

为什么很好,(2)但失败了?如果我删除它也很好。(4)(3)operator long

如何在不更改呼叫站点的情况下进行修复(3,4)

#include <string>
struct my
{
    std::string myVal;
    my(std::string val): myVal(val) {}

    operator std::string() { return myVal; };
    operator long() { return std::stol(myVal); };
};
int main()
{
    struct MyStruct
    {
        long n = my("1223"); // (1)
        std::string s = my("ascas"); // (2)
    } str;
    str.s = my("ascas"); // (3)
    str.n = my("1223"); // (4)
}
Run Code Online (Sandbox Code Playgroud)

错误信息

error C2593: 'operator =' is ambiguous
xstring(2667): note: could …
Run Code Online (Sandbox Code Playgroud)

c++ visual-c++ implicit-conversion move-constructor move-assignment-operator

8
推荐指数
2
解决办法
85
查看次数

如何检测一个类是否有移动构造函数?

我想检测(并使用 中的结果std::enable_if)C++ 类是否定义了移动构造函数。

以下程序打印MOVE,因此使用std::is_move_constructible不是这样做的方法:

#include <stdio.h>
#include <type_traits>
class C {
 public:
  C() { puts("C()"); }
  C(int) { puts("C(int)"); }
  ~C() { puts("~C()"); }
  C(const C&) { puts("C(const C&)"); }
  // C(C&&) { puts("C(C&&)"); }
  C& operator=(const C&) { puts("C="); return *this; }
};
int main(int argc, char** argv) {
  (void)argc; (void)argv;
  if (std::is_move_constructible<C>::value) puts("MOVE");
  return 0;
}
Run Code Online (Sandbox Code Playgroud)

我需要一个程序,MOVE只有当我取消注释包含&&.

c++ move-constructor c++11

7
推荐指数
1
解决办法
1936
查看次数

什么时候需要显式调用 std::move 以及什么时候不在 cpp 中?

我正在阅读 Stroustrup 的“C++ v2 之旅”。这当然不是一本 C++ 初学者的书,但很有趣。

我用谷歌搜索了一下,但对这个没有任何兴趣。

现在,我想我明白编译器何时可以使用移动构造函数,但显然我不明白。在这里,我展示了移动构造函数以及我认为会使用它的函数。事实并非如此。仅当我明确使用 std::move 时。为什么是这样?我的理解是,本地r将在返回时隐式“移动”。

template<typename T>
Vector<T>::Vector(Vector<T> && a) // move constructor
     :elem{a.elem},sz{a.sz}{
     a.elem=nullptr;
     a.sz=0;
}

template<typename T>
Vector<T> moveVectorAfterAdd(const Vector<T> &  v1, const Vector<T> & v2){
     Vector<T> r =   v1+v2;
     return std::move(r);
     //return r;
}

int main(void) {
     Vector<double> v1(1);
     Vector<double> v2=v1;
     Vector<double> v3=v2;

     Vector<double> v4=moveVectorAfterAdd(v1,v2);

     return 0;
}
Run Code Online (Sandbox Code Playgroud)

(顺便说一句,如果我实际上不使用 std::move,尽管编译时没有进行任何优化,lldb 甚至不会让我在移动构造函数中设置断点。)

很高兴收到所有澄清!

c++ move-constructor c++11

7
推荐指数
1
解决办法
2360
查看次数

理解 C++ move_constructible 概念实现

move_constructible我从cppreference得到了以下 C++ 概念的实现

template<typename _Tp>
concept move_constructible =
    constructible_from<_Tp, _Tp> &&
    convertible_to<_Tp, _Tp>;
Run Code Online (Sandbox Code Playgroud)

我不明白为什么这有效。我认为任何类型都可以转换为自身,因此第二个要求是毫无意义的(上帝,我一定是在某些方面错了)。另外,对于第一个要求,我希望constructible_from<_Tp, _Tp&&>检查类型是否可以从 rvalue-ref 构造(因此移动)。

请解释一下这个实现是如何工作的。

c++ move-constructor move-semantics c++-concepts c++20

7
推荐指数
1
解决办法
401
查看次数