Недавно пролистывал стандарт плюсов и наткнулся на интересную особенность конструкторов копирования (КК). Оказывается, что в КК можно передать сам конструируемый объект!
struct A
{
A(A&){}
};
void f()
{
A a(a);
}
Этот код полностью валиден, и действительно, объект а инициализируется сам собой. По стандарту идентификатор можно использовать сразу после декларатора, до инициализатора: как только мы сказали, что есть а (что такое а), можем его использовать.
Можем сделать вывод, что для создания объекта нам достаточно иметь КК A(A&):
struct A
{
A(A& a)
{
if (this == a)
{
// default ctor
}
else
{
// copy ctor
}
}
};
Исходя из вышенаписанного, легко можно понять, как разрулится следующий пример:
struct A
{
A(A&){}
A(int){}
};
void f()
{
A a(10);
{
A a(a);
}
}
void g()
{
A a(10);
{
A a = a;
}
}
void k()
{
const int a = 10;
{
A a[a];
}
}
В завершение хочу написать, что всё же такой "фичей" лучше не пользоваться, т.к. в ф-ции f() из последнего примера у компилятора от MS несколько отличное представление действительности. Он считает, что инициализация в КК не является инициализацией.