I'm trying to understand which is the most optimized way to pass arguments to functions. I got the answer for the book professional c++ but during some test I ran into a weird behavior.
It's clear that passing by reference when we want to change the variable and const reference when we don't want to change it is a good option.
In some cases, when we pass by reference, then we copy anyway the function parameter. For example:
void MyClass::func(const std::vector<double> &data)
{
data_ = data;
}
Here, data is a private member of MyClass. In this particular case, we pass data by const reference, but then we copy data. So, a possibility mentioned in the book 'Professional C++' is that in this case, it is better to pass by value and then move the data, if I understood correctly. The function becomes:
void MyClass::func(std::vector<double> data)
{
data_ = std::move(data);
}
if an lvalue is passed to func, it is copied into the data parameters and subsequently moved to data_. If an rvalue is passed to func(), it is moved into the data parameter, and moved again to data_. This makes completely sense.
However, if we pass a reference and then we use move, in this case, we move the object we passed and then if we try to use the vector we passed to the function, we get a core dump. Therefore this is not a good option.
void MyClass::func(std::vector<double> &data)
{
data_ = std::move(data);
}
Instead, if we pass a const reference, theoretically we cannot move data because we cannot change the status of the object:
void MyClass::func(const std::vector<double> &data)
{
data_ = std::move(data);
}
What I expect when I compile this is a compilation error. Instead, it compiles and also runs, but the only thing is that the data passed to the function is unchanged which is reasonable but why can I do something like that? I mean, why does this last code compile? Is it a bug or something I didn't understand?