tesla1060
tesla1060

Reputation: 2765

Is this the right way to use std::move?

I am trying to save a copy of char[10] in the below code snippet, just would like to know if this is the right way to use std::move and this will in fact save a copy of char[10] as Struct2 object is being constructed.

#include <string>
#include <iostream>
#include <cstring>
#include <memory>
using namespace std;


struct Struct1 {
    int a;
    string b;
    char c[10];
};

struct Struct2 {
    const Struct1 struct1;
    int d;
    string e;
};

int main() {
    int a = 10;
    auto b = "b";
    char c[10] = "12345";
    Struct1 struct1{a, b};
    strcpy(struct1.c, c);
    Struct2 str2{std::move(struct1), 10, "e"}; //<-- no copy of struct1.c, right?
    cout << str2.struct1.c << endl;
}

Also is there a better syntax in construct Struct2, if I dont want to copy char[10] twice(Struct1 will not be used other than as a field of Struct2)?

Upvotes: -1

Views: 358

Answers (3)

Den-Jason
Den-Jason

Reputation: 2573

Instead of polluting my previous answer, here is a suggestion:

If you want to use unique_ptr, try something like this. Unfortunately make_unique doesn't play nicely with initialiser lists so you have to define a non-default constructor (unless anyone out there knows a way around this?).

class Struct1
{
public:
    int a;
    string b;
    char c[10];

    Struct1::Struct1(int _a, string const&& _b, char const* _c) : a(_a), b(_b)
    {
        strcpy_s(c, 10, _c);
    }
};

using Struct1_unique = std::unique_ptr<Struct1>;

typedef struct 
{
    Struct1_unique pStruc1;
//  const Struct1 struct1;
    int d;
    string e;
}
tsStruct2;


int main() {
    int a = 10;
    auto b = "b";
    char c[10] = "12345";
    //Struct1 struct1{ a, b };
    Struct1_unique pStruc1 = std::make_unique<Struct1>(a, b, c);
    //strcpy_s(pStruc1->c, 10, c);
    tsStruct2 str2{ std::move(pStruc1), 10, "e" };
    cout << str2.pStruc1->c << endl;
    str2.pStruc1.reset();
}

So, once again, before the move you have: enter image description here

and after:

enter image description here

You can see that the ownership of the object has been transferred (pStruc1 now "empty") without doing any copying; the pointers to the object and the string data within have not changed. The reset at the end deallocates the object.

Upvotes: 0

Den-Jason
Den-Jason

Reputation: 2573

If you look at the variables with the debugger you can see that the only entity moved is the non-POD ("plain old data") string b. Before the move you have: enter image description here

and after the move you have: enter image description here

You will see that the 'b' string data has been copied to a new memory location and the old one is erased but it still has its original buffer at 0x00edfe40

As others have said, std::move is more concerned about transfer of ownership, ensuring that copies are not kept, moreso than avoiding copying memory around per-se.

Upvotes: 1

bolov
bolov

Reputation: 75688

A C array has the same semantics for move and copy. In other words a copy and a move of a C array do the exact same thing.

The advantage will be on std::string, e.g. member Struct1::b.

And yes, that is the correct syntax/usage of std:: move.

Upvotes: 2

Related Questions