Нуль-повторная инициализация структуры в С++
A POD struct
может быть инициализирован нулем в С++ 11 следующим образом:
SomeStruct s{};
Однако, что мне делать, если у меня уже есть экземпляр структуры, и я хочу повторно инициализировать его нулями? Кажется, что работает следующее:
s = {};
Может ли кто-нибудь указать соответствующий стандарт? Я предполагаю, что это то, что происходит:
- Создается новый нулевой инициализированный экземпляр.
- Новый экземпляр присваивается существующему экземпляру, вызывая неявный оператор присваивания.
Ответы
Ответ 1
Что вы ищете в [expr.ass]
В правой части
может появиться список бит-init-list. - присвоение скаляру, и в этом случае список инициализаторов должен иметь не более одного элемента. значение
x={v}
, где T - скалярный тип выражения x, - это значение x=T{v}
. Значение x={}
- x=T{}
. - присвоение объекту типа класса, и в этом случае список инициализаторов передается как аргумент функция оператора назначения, выбранная с помощью разрешения перегрузки (13.5.3, 13.3).
Итак, ваше предположение верно. Компилятор может оптимизировать ситуацию, но вы можете думать о ней как о создании инициализации с нулевой инициализацией и передать ее в operator=
.
Ответ 2
s = {};
небезопасен.
Проблема в том, что вы надеетесь, что она превратится в s = SomeStruct{};
. Однако, если s
имеет другую перегрузку для operator=
тогда это может быть предпочтительнее при разрешении перегрузки.
Итак, это действительно анти-шаблон. Как было предложено в другом потоке, вам лучше написать функцию, например:
template<typename T> void reset(T &t) { t = T{}; }
Я думаю, вы могли бы написать s = decltype(s){};
, если s
не был ссылкой.