Разница между return {} и return Object {}

Есть ли существенная разница между этими двумя функциями?

struct Object {
    Object(int i) : i{i}
    {
    }

    int i;
};

Object f() { return {1}; }
Object g() { return Object{1}; }

Ответ 1

Первый - это copy- -инициализация списка, для построения возвращаемого значения будет выбран конструктор approriate (т.е. Object::Object(int)).

Второй построит временный Object помощью инициализации direct-list-инициализацией (который также вызывает Object::Object(int)), а затем скопирует его в возвращаемое значение. Из-за копирования elision (что гарантировано от С++ 17) конструкция copy- или move- здесь опущена.

Так что для вашего примера они имеют тот же эффект; Object::Object(int) используется для построения возвращаемого значения. Обратите внимание, что для 1-го случая, если конструктор explicit он не будет использоваться.

  • direct-list-initialization (рассматриваются как явные, так и неявные конструкторы)

  • copy- list-initialization (рассматриваются как явные, так и неявные конструкторы, но можно назвать только неявные конструкторы)

Ответ 2

Никакой разницы в вашем примере как написано. Но разница будет возникать, если вы отметите конструктор explicit. Тогда только g будет правильным, потому что он выполняет прямую инициализацию, тогда как f выполняет форму инициализации копии и не может использовать явный конструктор.