Почему случайные объекты распределения могут быть инициализированы конструктором через {}, кроме ()? [Дубликат]

Согласно этому интервью с Will Kahan , они были основаны на форматах VAX F и G эпохи.

Конечно, что doesn «Ответ на вопрос о том, как эти форматы были выбраны ...

7
задан Community 23 May 2017 в 11:54
поделиться

4 ответа

В чем разница между Object obj(args...) и Object obj{args...}?

Первая - direct-initialization , а вторая - direct -list-инициализации . Это упоминается в двух разных разделах:

§8.5 / 16 [dcl.init]

Инициализация, которая происходит в формах

 T x(a);
 T x{a};

, а также в выражениях new (5.3.4), static_cast (5.2.9), преобразования типа функциональных обозначений (5.2.3) и инициализаторы базиса и члена (12.6. 2) называется прямой инициализацией .

и §8.5.4 / 1 [dcl.init.list]

List-initialization - инициализация объекта или ссылки из braced-init-list . Такой инициализатор называется списком инициализаторов , а разделяемые запятой -инициализаторы-предложения списка называются элементами списка инициализаторов. Список инициализаторов может быть пустым. Инициализация списка может возникать в контекстах с прямой инициализацией или копированием; list-initialization в контексте прямой инициализации называется direct-list-initialization , а инициализация списка в контексте инициализации копирования называется copy-list-initial-initialization .


Есть несколько отличий между ними:

  • Если построенный тип имеет конструктор, который принимает аргумент initializer_list, direct-list-initialization всегда будет поддерживать этот конструктор. Другие конструкторы будут рассмотрены только в том случае, если конструктор initializer_list не является жизнеспособным. §13.3.1.7 / 1 [over.match.list]
  • direct-list-initialization не позволяет сужать преобразования в списке аргументов. §8.5.4 / 3 [dcl.init.list]
  • Если инициализированный тип является агрегатом, direct-list-initialization будет выполнять агрегатная инициализация. §8.5.4 / 3 [dcl.init.list]
  • Порядок оценки элементов braced-init-list из слева направо. §8.5.4 / 4 [dcl.init.list]
  • Вы можете избежать наиболее неприятного анализа с помощью direct-list-initialization

& nbsp;

  struct foo{};
  struct bar 
  {    
    bar(foo const&) {}
  };

  bar b1(foo()); // most vexing parse
  bar b2(foo{}); // all 3 of the following construct objects of type bar
  bar b3{foo()};
  bar b4{foo{}};
5
ответ дан Praetorian 16 August 2018 в 05:37
поделиться

В чем разница между Object obj (args ...) и Object obj {args ...}?

{args ...} будет предпочтительнее конструктор с список initializer_list по другим законным кандидатам.

std::vector<int> v(10); // vector of size 10
std::vector<int> v{10}; // vector initialized with a single element, (int) 10

С другой стороны, вы отказываетесь от неявного сужения.

std::vector<int> v(10.5); // vector of size 10
std::vector<int> v{10.5}; // illegal - no compile
std::vector<float> v{10.5}; // vector initialized with a single element, (float) 10.5
1
ответ дан codenheim 16 August 2018 в 05:37
поделиться

В чем разница между Object obj (args ...) и Object obj {args ...}? и почему Скотт говорит так.

. Разница в том, что в первом случае порядок оценки аргументов не имеет значения (т. е. неуказан), но в последнем случае порядок остается слева (например, в котором они появляются).

Следующий текст из 5.2.2 / 8 [expr.call] (n3690) относится к форме Object(args...):

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

И текст из $ 8.5.4 / 4 [dcl.init.list] (n3690) имеет дело с Object{args...} form:

В списке инициализаторов списка с привязкой-инициализацией предложения инициализатора, включая все, которые являются результатом разложений пакетов (14.5.3), оцениваются в порядок, в котором они появляются. То есть вычисление каждого значения и побочный эффект, связанный с заданным предложением инициализатора, секвенируются перед вычислением каждого значения и побочным эффектом, связанным с любым предложением инициализатора, которое следует за ним в списке списка инициализаторов, разделенных запятыми. [Примечание: это порядок оценки выполняется независимо от семантики инициализации; например, он применяется, когда элементы списка инициализатора интерпретируются как аргументы вызова конструктора, хотя обычно нет ограничений последовательности для аргументов вызова. - end note]

Ну, это означает:

 int f() { static int i = 10; return ++i; }  //increment the static int!

 Object obj(f(), f()); //is it obj(11,12) or obj(12,11)? Unspecified. 

 Object obj{f(), f()}; //it is obj(11,12). Guaranteed.

Обратите внимание, что GCC (4.7.0 и 4.7.2) имеют ошибку из-за форма {} не работает так, как должна . Я не уверен, исправлена ​​ли она в текущей версии.

Надеюсь, что это поможет.

1
ответ дан Community 16 August 2018 в 05:37
поделиться

Поведение Object obj(args...) и Object{args...} зависит от конструкторов, определенных в Object.

Возьмем следующий пример:

#include <iostream>
#include <initializer_list>

struct A
{
   A(int a, int b) {std::cout << "Came to A::A()\n";}
};

struct B
{
   B(int a, int b) {std::cout << "Came to B::B(int, int)\n";}
   B(std::initializer_list<int> in) {std::cout << "Came to B::B(std::initializer_list<int>)\n";}
};

int main()
{
   A a1(10, 20); // Resolves to A(int, int)
   A a2{10, 20}; // Resolves to A(int, int)
   A a3{30};     // Does not resolve to anything. It's a compiler error.

   B b1(10, 20); // Resolves to B(int, int)
   B b2{10, 20}; // Resolves to B(std::initializer_list<int> )
   B b3{30};     // Resolves to B(std::initializer_list<int> )

}
2
ответ дан R Sahu 16 August 2018 в 05:37
поделиться
Другие вопросы по тегам:

Похожие вопросы: