2013-06-05 3 views
2

Если я это сделать:станд :: initializer_list и оператор =

MyClass a=b; 

Это использует конструктор копирования для инициализации a, и перегрузка = оператор не участвует, не так ли?

Оператор = будет использоваться, если a уже был инициализирован, а затем я позже присвоил его чему-то еще.

Я видел this:

S(std::initializer_list<T> l) : v(l) { 

Используется как:

S<int> s = {1, 2, 3, 4, 5}; // direct list-initialization 

Это интересно. Это инициализация и использует оператор =, но он вызывает конструктор, который не является конструктором копирования. Почему это не вместо принимать синтаксис так:

S<int> s {1, 2, 3, 4, 5}; 

Вот как std::vectorconstructor с std::initializer_list работ. Кажется запутанным использовать оператор = для инициализации объекта, когда этот оператор не вызывает построение копии, не так ли?

+0

[Тест] (http://coliru.stacked-crooked.com/view?id=32e42256c131b9f31d69b59d16ccecbf-50d9cfc8a1d350e7409e81e87c2653ba) –

ответ

11

Это использует конструктор копирования для инициализации a, а перегрузка оператора = не задействована, правильно?

Точно.

Почему вместо этого не требуется синтаксис: [...]

Вы можете использовать обе формы, и они в основном эквивалентны, за исключением того, что форма использования = называется копирования списка инициализация за исключением, и это требует не- explicit конструктор (благодаря Nicol Болас для коррекции).

Форма без =, с другой стороны, называется прямой список инициализация и она работает (довольно интуитивно) путем непосредственного построения вашего объекта из инициализаторе (передавая инициализатору в качестве аргумента в конструктор объект, подлежащий инициализации). Независимо от того, является ли конструктор explicit, здесь не имеет значения.

Итак, две формы эквивалентны, за исключением того факта, что Идентификация-копия-копия не будет работать, если ваш конструктор explicit. Если это не так, то какую форму выбрать - это в основном вопрос стиля.

+0

[Explicit] (http://coliru.stacked-crooked.com/view?id=b09efd59be75e347c103c4bde4158689-50d9cfc8a1d350e7409e81e87c2653ba) –

+0

@MarkGarcia: Точно :) –

+0

я бы себе представить, что так как он проходит список конструктору, вы могли бы также напишите его как третий вариант, как 'S s ({1, 2, 3, 4, 5});' – johnbakers

3

MyClass a=b; использует конструктор копирования, только если b имеет тип MyClass.

Если b был OtherClass, вам потребуется еще один конструктор, который не конструктор копирования, только другой пользовательский конструктор принимает OtherClass в качестве аргумента (или более вероятно const OtherClass&, но это не имеет отношение к вопросу - только предотвращающему nitpickers :).

То же самое с вашим примером с initializer_list: Это обычный конструктор для типа S, который принимает список инициализаций в качестве аргумента. В этом смысле он не отличается от некоторого гипотетического конструктора S(int n).

Представьте себе, если у вас:

S(int n) : v(n) {} // ctor taking an int 

Вы можете создать экземпляр, как это:

S s = 4; 

То же самое для списка инициализации.

+0

Хороший аналогичный пример. –