Унифицированная инициализация в С++ 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
Ответы
Ответ 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 и простых объектов вы можете использовать {}
и ()
взаимозаменяемые.