Наивный, оптимистичный и о ... так неправильный взгляд на унифицированный синтаксис инициализации С ++ 11
Я думал, что, поскольку объекты пользовательского типа C ++ 11 должны быть созданы с новым синтаксисом {...}
вместо старого синтаксиса (...)
(за исключением конструктора, перегруженного для std::initializer_list
и подобных параметров (например, std::vector
: size ctor vs 1 elem init_list ctor)) .
Преимущества: отсутствие узких неявных преобразований, отсутствие проблем с самым неприятным синтаксическим анализом, согласованность (?). Я не видел проблем, так как думал, что они такие же (кроме приведенного примера).
Но это не так.
Рассказ о чистом безумии
{}
вызывает конструктор по умолчанию.
... За исключением случаев:
- конструктор по умолчанию удаляется и
- другие конструкторы не определены.
Тогда похоже, что это скорее значение инициализирует объект? ... Даже если объект удалил конструктор по умолчанию, {}
может создать объект. Разве это не превосходит всю цель удаленного конструктора?
... За исключением случаев:
- объект имеет удаленный конструктор по умолчанию и
- другие конструкторы определены.
Затем он терпит неудачу с call to deleted constructor
.
... За исключением случаев:
- у объекта есть удаленный конструктор и
- никакой другой конструктор не определен и
- по крайней мере, нестатический член данных.
Затем происходит сбой с отсутствующими инициализаторами полей.
Но тогда вы можете использовать {value}
для создания объекта.
Хорошо, возможно, это то же самое, что и первое исключение (значение инициализации объекта)
... За исключением случаев:
- у класса есть удаленный конструктор
- и по крайней мере один член данных в классе инициализирован по умолчанию.
Тогда ни {}
, ни {value}
не могут создать объект.
Я уверен, что пропустил несколько. Ирония заключается в том, что это называется унифицированным синтаксисом инициализации. Я повторяю еще раз: синтаксис инициализации UNIFORM.
Что это за безумие?
Сценарий А
Удален конструктор по умолчанию:
struct foo {
foo() = delete;
};
// All bellow OK (no errors, no warnings)
foo f = foo{};
foo f = {};
foo f{}; // will use only this from now on.
Сценарий B
Удален конструктор по умолчанию, остальные конструкторы удалены
struct foo {
foo() = delete;
foo(int) = delete;
};
foo f{}; // OK
Сценарий C
Удален конструктор по умолчанию, определены другие конструкторы
struct foo {
foo() = delete;
foo(int) {};
};
foo f{}; // error call to deleted constructor
Сценарий D
Удален конструктор по умолчанию, другие конструкторы не определены, член данных
struct foo {
int a;
foo() = delete;
};
foo f{}; // error use of deleted function foo::foo()
foo f{3}; // OK
Сценарий E
Удален конструктор по умолчанию, удален конструктор T, член данных T
struct foo {
int a;
foo() = delete;
foo(int) = delete;
};
foo f{}; // ERROR: missing initializer
foo f{3}; // OK
Сценарий F
Удален конструктор по умолчанию, инициализаторы членов данных класса
struct foo {
int a = 3;
foo() = delete;
};
/* Fa */ foo f{}; // ERROR: use of deleted function `foo::foo()`
/* Fb */ foo f{3}; // ERROR: no matching function to call `foo::foo(init list)`
static
означает очень разные вещи в зависимости от контекста (на самом деле есть только два очень разных значения и в явно разных контекстах). Затем изобретаетсяdecltype
с двумя тонко разными значениями с очень тонким разным использованием:identifier
vs:(identifier)
- person curiousguy   schedule 28.07.2018