Недавно я столкнулся с некоторыми странными ошибками из-за такого кода.
vector<int> a(a);
Почему код выше принят? Когда это необходимо? И как попросить компилятор запретить такое использование? Спасибо.
Недавно я столкнулся с некоторыми странными ошибками из-за такого кода.
vector<int> a(a);
Почему код выше принят? Когда это необходимо? И как попросить компилятор запретить такое использование? Спасибо.
Самый распространенный вариант использования для этого - на самом деле в C, а не на С++ (вы не должны использовать malloc
в С++, хотя можете), но в этом случае С++ обратная совместимость:
mytype *p = malloc(sizeof *p);
Предоставив использование выражения p
в выражении инициализатора, вы можете передать sizeof *p
в malloc
, гарантируя, что независимо от размера mytype
будет выделен нужный размер. Если вам не разрешалось делать *p
, тогда вышеприведенное выражение должно было бы иметь тип mytype
дважды, а последующее обслуживание в коде может обновлять один из типов и не обновлять другой.
Это необычная конструкция, которая действительно используется, но может быть полезна, если класс имеет конструктор, который по какой-либо причине ссылается на какой-либо другой объект, и вызывающий может захотеть зацикливать объект на свою собственную инициализацию.
Вот надуманный пример:
#include <iostream>
using namespace std;
struct PrintAnAddress {
PrintAnAddress()
: msg_("")
, addr_(NULL)
{ }
PrintAnAddress( char const *msg, PrintAnAddress const &that )
: msg_( msg )
, addr_( &that )
{ }
void operator()( ostream &os ) const {
cout << msg_ << addr_ << endl;
}
private:
char const *msg_;
PrintAnAddress const *addr_;
};
int main() {
PrintAnAddress p1;
PrintAnAddress p2( "p1:", p1 );
PrintAnAddress p3( "self:", p3 );
p1(cout);
p2(cout);
p3(cout);
}
Когда p2
определен, он настроен на печать адреса p1
, но когда p3
определен, он настроен на печать собственного адреса. Если переменная p3
еще не была в области видимости, было бы невозможно ссылаться на нее, чтобы передать ее при ее инициализации. (По крайней мере, не без инструментального класса и каким-то образом получить доступ к указателю this
.)
Я уверен, что есть полезные и действительные приложения этой конструкции, но, как я уже сказал, это довольно необычно, поэтому никто не приходит мне в голову в данный момент.