Топик навеян ссылкой, которую дал Pinkbyte в нуботреде. В комментариях к статье сказано, что компилятор будет создавать временный объект и вызывать конструктор копирования для версии оператора присваивания приведенной ниже.
Тут оптимальнее переложить создание копии на компилятор, раз уж он всё равно позволяет это делать автоматически (получаем аргумент по значению, а не по ссылке):
Две других реализации этого же оператора присваивания для подопытного демо-класса для наглядности закомментированы.
#include <iostream>
using namespace std;
class Intvec
{
public:
explicit Intvec(size_t num = 0)
: m_size(num), m_data(new int[m_size])
{
log("constructor");
}
~Intvec()
{
log("destructor");
if (m_data) {
delete[] m_data;
m_data = 0;
}
}
Intvec(const Intvec& other)
: m_size(other.m_size), m_data(new int[m_size])
{
log("copy constructor");
for (size_t i = 0; i < m_size; ++i)
m_data[i] = other.m_data[i];
}
Intvec& operator=(Intvec other)
{
log("copy assignment operator");
swap(m_size, other.m_size);
swap(m_data, other.m_data);
return *this;
}
/*Intvec& operator=(const Intvec& other)
{
log("copy assignment operator");
Intvec tmp(other);
std::swap(m_size, tmp.m_size);
std::swap(m_data, tmp.m_data);
return *this;
} */
/* Intvec& operator=(Intvec&& other) // Now we are smart enough to use move semantics
{
log("move assignment operator");
std::swap(m_size, other.m_size);
std::swap(m_data, other.m_data);
return *this;
} */
private:
void log(const char* msg)
{
std::cout << "[" << this << "] " << msg << "\n";
}
size_t m_size;
int* m_data;
};
int main(int argc, char* argv[]) {
//Intvec v1(42);
Intvec v2;
cout << "assigning rvalue..." << endl;
v2 = Intvec(21);
//v2 = v1;
cout << "ended assigning rvalue..." << endl;
return 0;
}
Как видим на практике этого не происходит — конструктор копирования не вызывается. У меня только один вопрос: Это уже copy elision от умного компилятора или я не допер?
Ведь тогда правка комментатора лишает пример статьи всякого смысла и наглядности, не? ))