Для примитивных типов оба эквивалентны, но для типов классов, определяемых пользователем, есть разница. В обоих случаях выполняемый код будет одинаковым (после выполнения базовой оптимизации), но требования к типам различаются, если элемент, из которого мы инициализируем, не относится к тому типу, который мы создаем.
инициализация копирования (T t = u;
) эквивалентна конструкции копирования из временного объекта типа T
, который был неявно преобразован из u
в t
. С другой стороны, прямая инициализация эквивалентна прямому вызову соответствующего конструктора.
Хотя в большинстве случаев разницы не будет, если конструктор, принимающий u
, объявлен explicit
или если copy-constructor недоступен, то инициализация копирования завершится ошибкой:
struct A {
explicit A( int ) {}
};
struct B {
B( int ) {}
private:
B( B const & );
};
int main() {
A a(1); // ok
B b(1); // ok
// A a2 = 1; // error: cannot convert from int to A
// B b2 = 1; // error: B( B const & ) is not accessible
}
По некоторым историческим соображениям, изначально примитивные типы должны были быть инициализированы с помощью copy-initialization. Когда * список-инициализаторов * были добавлены к языку для инициализации атрибутов членов из класса, было решено, что примитивные типы должны быть инициализированы с тем же синтаксисом, что и классы, чтобы синтаксис в списке инициализаторов был единообразным и простым. В то же время разрешение инициализации классов с помощью copy-initialization приближает определяемые пользователем типы к примитивным типам. Различия в двух форматах инициализации очевидны: int a = 5.0;
обрабатывается как преобразование из 5.0
в int
, а затем инициализация a
из int
. То же самое и с пользовательскими типами: T u = v;
обрабатывается как преобразование из v
в T
, а затем копируется построение u
из этого преобразованного значения.
person
David Rodríguez - dribeas
schedule
19.07.2011