Fun with C++
Feb. 27th, 2011 12:24 pmПо мотивам цього посту.
Хоч я і люблю і поважаю C++, но такі приколи мене бісять.
У масивів в C++ немає конструктора копії і оператора присвоювання. Тобто їх не можна ініціалізувати так:
У стандарті у параграфі 8.5.1 явно прописана ініціалізація масивів через списки ініціалізації (як масив a у прикладі вище) а у 8.5.2 через літерали (наприклад, char a[] = "abcdef";).
З іншого боку, стандарт гарантує (параграф 12.8) що для класів буде неявно створено конструктор копії (за виключенням випадків перелічених у п. 12 параграфу) і оператор присвоювання (за виключенням випадків перелічених у п. 24 параграфу) якщо його не декларувати явно. Таким чином, наступний код абсолютно коректний:
12.8.16: "if the member is an array, each element is direct-initialized with the correcponding base or member of x"
12.8.29: "if the subobject is an array, each element is assigned, in the manner appropriate to the element type"
Мораль:не вмієш срать - не мучай жопу не використовуйте масиви там де без них можна обійтись (використанням std::vector, tr1::array або boost::array).
PS: під час написання посту використовувався "Working Draft, Standard for Programming Language C++", ревізія N3126 від 27/11/2010 і компілятор g++ версії 4.4.4.
Хоч я і люблю і поважаю C++, но такі приколи мене бісять.
У масивів в C++ немає конструктора копії і оператора присвоювання. Тобто їх не можна ініціалізувати так:
int a[3] = {1, 2, 3}; // ok
int b[3](a); // fail
int c[3] = a; // fail
int d[3];
d = a; // fail
У стандарті у параграфі 8.5.1 явно прописана ініціалізація масивів через списки ініціалізації (як масив a у прикладі вище) а у 8.5.2 через літерали (наприклад, char a[] = "abcdef";).
З іншого боку, стандарт гарантує (параграф 12.8) що для класів буде неявно створено конструктор копії (за виключенням випадків перелічених у п. 12 параграфу) і оператор присвоювання (за виключенням випадків перелічених у п. 24 параграфу) якщо його не декларувати явно. Таким чином, наступний код абсолютно коректний:
struct A {
int arr[3];
};
A a = {{1, 2, 3}}; // ok
A b(a); // ok
A c = a; // ok
A d;
d = a; // ok
12.8.16: "if the member is an array, each element is direct-initialized with the correcponding base or member of x"
12.8.29: "if the subobject is an array, each element is assigned, in the manner appropriate to the element type"
Мораль:
PS: під час написання посту використовувався "Working Draft, Standard for Programming Language C++", ревізія N3126 від 27/11/2010 і компілятор g++ версії 4.4.4.