Аргумент по умолчанию с использованием фигурных скобок инициализатора

У меня есть этот фрагмент кода, который, кажется, работает хорошо:

class foo{/* some member variables and functions*/};
void do_somthing(foo x={}){}
int main(){
  do_somthing();
}

Я использовал, чтобы использовать void do_somthing(foo x=foo()){} по умолчанию x аргумент, но я вижу этот путь ={} в какой-то книге или онлайн-примере (не помню). Это полностью нормально использовать? Есть ли разница между этими двумя методами?

1 ответ

Решение

foo x=foo() инициализация копии,

Инициализирует объект из другого объекта

а также foo() это инициализация значения.

Это инициализация, выполняемая, когда переменная создается с пустым инициализатором.

foo x={} это агрегатная инициализация.

Инициализирует агрегат из списка braced-init-list

Если количество предложений инициализатора меньше количества членов и баз (начиная с C++17) или список инициализаторов полностью пуст, остальные члены и базы (начиная с C++17) инициализируются инициализаторами по умолчанию, если они предоставляются в определении класса, и в противном случае (начиная с C++14) пустыми списками, которые выполняют инициализацию значения.

Таким образом, результат в этом случае одинаков (оба значения инициализированы).

И последствия инициализации значения в этом случае:

если T является типом класса с конструктором по умолчанию, который не предоставлен и не удален пользователем (то есть это может быть класс с неявно определенным или дефолтным конструктором по умолчанию), объект инициализируется нулями

Наконец, эффекты нулевой инициализации в этом случае:

Если T является скалярным типом, начальное значение объекта является целочисленной константой ноль, явно преобразованной в T.

Если T является типом класса, не являющимся объединением, все базовые классы и нестатические члены данных инициализируются нулями, а все заполнение инициализируется нулевыми битами. Конструкторы, если таковые имеются, игнорируются.

Другие вопросы по тегам