I was wondering why it is needed to use const A& in this situation, Why can't I use just A&? according to what I read is because it specified that it won't change the object. Is there any other reason? I would like a better explanation.
Code:
#include<iostream>
#include<set>
class A{
public:
int x;
A(int x=0): x{x} {std::cout<<"Construct"<<std::endl;};
A(const A& rhs) {x=rhs.x;std::cout<<"Copy"<<std::endl;}
};
bool operator < (const A& lhs,const A& rhs) {return lhs.x<rhs.x;}
int main(){
std::set<A> Set;
A a(10);
Set.insert(a);
Set.emplace(10);
return 0;
}
CodePudding user response:
A&
is an lvalue reference, which means it can change the thing it's looking at. With
A(A& rhs)
you can call it like
int x = 10;
A a(x);
And then any changes to rhs
in the constructor will change the actual variable x
. And that's fine. But when you do
A a(10);
That's a problem. Because if someone changes rhs
in the constructor, that means we have to "change" the number 10
, and that's not really even a meaningful thing to do. 10 = 1
is nonsense in C , for instance.
const A&
is a guarantee that we aren't going to change the thing being pointed to, so it becomes safe to pass a temporary value like 10
to the function.
If we knew it was always a "small" datatype like int
, we might take it by value, but we don't want to take an A
as argument, since some types (like vectors) can be expensive to copy, and others (like unique_ptr
) are outright impossible to copy.
Depending on your use case, you can consider using A&&
, an rvalue reference. This is useful if you intend to move the value into the class you're constructing, rather than make a copy of it. You can read more about move semantics on this question, but if you're just starting out in C , it's probably best to stay away from rvalue references. It is good to be aware that they exist, though.