Подтвердить что ты не робот

Унифицированная инициализация в С++ 0x, когда использовать() вместо {}?

Есть ли правило для решения, когда использовать старый синтаксис () вместо нового синтаксиса {}?

Для инициализации структуры:

struct myclass
{
    myclass(int px, int py) : x(px), y(py) {}
private:
    int x, y;
};
...
myclass object{0, 0};

Теперь, например, в случае vector он имеет много конструкторов. Всякий раз, когда я делаю следующее:

vector<double> numbers{10};

Я получаю вектор элемента 1 вместо одного с 10 элементами, поскольку один из конструкторов:

explicit vector ( size_type n, const T& value= T(), const Allocator& = Allocator() );

Мое подозрение в том, что всякий раз, когда класс определяет конструктор initializer list, как в случае с вектором, он вызывается с синтаксисом {}.

Итак, это то, что я считаю правильным. то есть Должен ли я вернуться к старому синтаксису только тогда, когда класс определяет конструктор списка инициализаторов для вызова другого конструктора?, например. для исправления приведенного выше кода:

vector<double> numbers(10); // 10 elements instead of just one element with value=10
4b9b3361

Ответ 1

Я нашел ответ в стандартных документах (последний проект). Надеюсь, я попытаюсь объяснить, что я понял.

Во-первых, если класс определяет конструктор списка инициализации, то он используется всякий раз, когда подходит:

§ 8.5.4 (стр. 203)

Конструкторы списка инициализаторов предпочтение отдается другим конструкторам в list-initialization (13.3.1.7).

Я думаю, что это отличная возможность иметь, устраняя головную боль, связанную с неравномерным стилем:)

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

В принципе, представьте, что std::vector не имеет конструктора списка инициализаторов, тогда следующий создаст вектор с 10 элементами:

std::vector<int> numbers{10};

Добавив конструктор списка инициализаторов, компилятор предпочтет его над другим конструктором из-за синтаксиса {}. Такое поведение произойдет, потому что элементы init-list {10} принимаются с использованием конструктора списка инициализации. Если нет приемлемого преобразования, должен использоваться любой другой конструктор, например:

std::vector<string> vec{10};
// a vector of 10 elements.
// the usual constructor got used because "{0}"
// is not accepted as an init-list of type string.

Ответ 2

Взгляните на это:

http://www.informit.com/guides/content.aspx?g=cplusplus&seqNum=453&rll=1

Использование инициализаторов {} -style для переменной не имеет прямого сопоставления спискам инициализации для любых конструкторов класса. Эти списки инициализации конструктора могут быть добавлены/удалены/изменены без нарушения существующих абонентов.

В основном различное поведение контейнера является особенным и требует специального кода в этом контейнере, в частности, конструктора, принимающего std::initializer_list. Для POD и простых объектов вы можете использовать {} и () взаимозаменяемые.