Инициализация с помощью "var {args}" - это новая функция C ++ 0x или просто синтаксический сахар? - PullRequest
3 голосов
/ 12 августа 2011

Я читал C ++ 0x faq и наткнулся на раздел, подробно описывающий списки инициализаторов.Примеры были в основном вариациями:

vector<int> vi = { 1, 2, 3 };
vector<int> vj({1, 2, 3});
// etc.

Однако также была указана форма:

vector<int> vk{2};

Эта форма появляется в другом месте в faq, и мне любопытно, является ли онасемантически отличается от исходных двух форм или просто синтаксический сахар для vk({x, y, z}).

Ответы [ 3 ]

6 голосов
/ 13 августа 2011

Форма ({1, 2, 3}) вызывает конструкторы vector<int> напрямую и передает в качестве первого аргумента {1, 2, 3}.Вы могли бы передать больше аргументов

vector<int> vk({1, 2, 3}, myAllocator);

Если бы у vector<int> не было конструктора, чей первый параметр - initializer_list, или другого типа, который мог бы быть инициализирован {1, 2, 3} (как, например, другой контейнерный класс)), это не будет работать.В вашем случае это работает, потому что vector<int> на самом деле имеет конструктор, чей первый параметр - initializer_list<int>.Это так же, как при обычных вызовах функций

void f(vector<int> const& vk);
int main() { f({1, 2, 3}); }

Если вы опустите скобки, как в vector<int> vk{1, 2, 3}, точное значение зависит от класса.vector<int> имеет конструктор списка инициализатора, который является конструктором с первым параметром типа initializer_list<int> (необязательно ссылкой на него) и всеми другими параметрами с аргументами по умолчанию.Если класс имеет такой конструктор, то список инициализаторов передается этому конструктору.В качестве альтернативы класс может быть просто агрегатом (например, struct A { int a; int b; int c; };, тогда список инициализатора будет инициализировать членов) или иметь конструктор, который принимает 3 отдельные int аргументы.

Наконец, форма = { 1, 2, 3 } практически идентична версии, в которой опущены скобки (то есть просто удаляются =), за исключением того, что она запрещает использовать явные конструкторы (т. Е. Если они объявили ее как explicit vector(initializer_list<int>); иливместо этого они объявили explicit vector(int, int, int);, если вы используете = { 1, 2, 3 }), это приведет к ошибке.

1 голос
/ 12 августа 2011

Один - равномерная инициализация , а другой - списки инициализаторов .Это две разные вещи, хотя, как вы можете видеть, они могут генерировать сходный синтаксис.

vector<int> vk{2};

- это единообразная инициализация, остальные два - списки инициализаторов.

0 голосов
/ 13 августа 2011

Равномерная инициализация предотвращает сужение преобразований, т.е. преобразований, которые могут привести к потере данных:

#include <vector>

std::vector<float> v{1.0F, 2.0F, 3.0F}; // OK: 

std::vector<float> w{1.0, 2.0, 3.0}; // OK: doubles could be put into floats without loss.

std::vector<int> j{1.1, 2.2, 3.3}; // error: narrowing

std::vector<int> k{1L, 2L, 3L}; // OK: the long numbers can be represented as int without loss.

std::vector<int> l{0xfacebeefL, 0xdeadbabeL, 0xfadecabeL}; // error: narrowing.
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...