Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

are C++ structs fully copied or just referenced when assigned with '='?

Tags:

c++

struct

If structs are fully copied, then the first loop is more expensive than the second one, because it is performing an additional copy for each element of v.

vector<MyStruct> v;

for (int i = 0; i < v.size(); ++i) {
    MyStruct s = v[i];
    doSomething(s);
}

for (int i = 0; i < v.size(); ++i) {
    doSomething(v[i]);
}

Suppose I want to write efficient code (as in loop 2) but at the same time I want to name the MyStruct elements that I draw from v (as in loop 1). Can I do that?

like image 467
user2460978 Avatar asked Dec 04 '22 07:12

user2460978


2 Answers

Structs (and all variables for that matter) are indeed fully copied when you use =. Overloading the = operator and the copy constructor can give you more control over what happens, but there is no way you can use these to change the behavior from copying to referencing. You can work around this by creating a reference like this:

for (int i = 0; i < v.size(); ++i) {
    MyStruct& s = v[i]; //& creates reference; no copying performed
    doSomething(s);
}

Note that the struct will still be fully copied when you pass it to the function, unless the argument is declared as a reference. This is a common pattern when taking structs as arguments. For instance,

void doSomething(structType x);

Will generally perform poorer than

void doSomething(const structType& x);

If sizeof structType is greater than sizeof structType*. The const is used to prevent the function from modifying the argument, imitating pass-by-value behavior.

like image 122
ApproachingDarknessFish Avatar answered Dec 09 '22 13:12

ApproachingDarknessFish


In your first example, the object will be copied over and you will have to deal with the cost of the overhead of the copy.

If you don't want the cost of the over head, but still want to have a local object then you could use a reference.

for (int i = 0; i < v.size(); ++i) {
    MyStruct& s = v[i];
    doSomething(s);
}
like image 32
Caesar Avatar answered Dec 09 '22 13:12

Caesar