Что означает заявление
return {};
в C ++ 11 указывают, а когда использовать вместо (скажем)
return NULL;
или
return nullptr;
Что означает заявление
return {};
в C ++ 11 указывают, а когда использовать вместо (скажем)
return NULL;
или
return nullptr;
return;
без значения?return;
С другой стороны,return{};
это допустимо, если у вас есть возвращаемый тип.Ответы:
return {};
указывает "вернуть объект типа возвращаемого значения функции, инициализированный пустым инициализатором списка ". Точное поведение зависит от типа возвращаемого объекта.С cppreference.com (поскольку OP помечен как C ++ 11, я исключил правила из C ++ 14 и C ++ 17; дополнительную информацию см. По ссылке):
До C ++ 11 для функции, возвращающей a
std::string
, вы должны были написать:Используя синтаксис фигурных скобок в C ++ 11, вам не нужно повторять тип:
return NULL
иreturn nullptr
должен использоваться, когда функция возвращает тип указателя:Однако
NULL
не рекомендуется, начиная с C ++ 11, потому что это просто псевдоним целочисленного значения (0), аnullptr
это реальный тип указателя:источник
Это, вероятно, сбивает с толку:
Вероятно, это не так:
источник
initializer_list
конструктор, разве он не будет использоваться, если конструктор по умолчанию недоступен?return {}
НЕ эквивалентноreturn SomeObjectWithADefaultConstructor{};
return {};
означает, что{}
это инициализатор для возвращаемого значения . Возвращаемое значение инициализируется пустым списком.Вот некоторая предыстория возвращаемого значения , основанная на [stmt.return] в Стандарте C ++:
Для функции, которая возвращается по значению (т. Е. Тип возвращаемого значения не является ссылкой и не
void
), существует временный объект, называемый возвращаемым значением . Этот объект создаетсяreturn
оператором, и его инициализаторы зависят от того, что было в операторе возврата.Возвращаемое значение сохраняется до конца полного выражения в коде, вызвавшем функцию; если он имеет тип класса, то его деструктор будет запущен, если его время жизни не будет продлено вызывающим, привязавшим ссылку непосредственно к нему.
Возвращаемое значение можно инициализировать двумя разными способами:
return some_expression;
- возвращаемое значение инициализируется копией изsome_expression
return { possibly_empty_list };
- возвращаемое значение инициализируется списком из списка.Предполагая
T
, что это тип возвращаемого значения функции, обратите внимание, чтоreturn T{};
это отличается отreturn {}
: в первом случае создается временное значениеT{}
, а затем возвращаемое значение инициализируется копией из этого временного.Это не будет скомпилировано, если
T
нет доступного конструктора копирования / перемещения, ноreturn {};
будет успешным, даже если эти конструкторы отсутствуют. Соответственно,return T{};
могут отображаться побочные эффекты конструктора копирования и т. Д., Хотя это контекст исключения копирования, поэтому может и не быть.Вот краткое описание инициализации списков в C ++ 14 (N4140 [dcl.init.list] / 3), где инициализатором является пустой список:
T
является агрегатом, то каждый член инициализируется из его инициализатора фигурной скобки или равного-равного, если он есть, в противном случае, как если бы by{}
(поэтому применяйте эти шаги рекурсивно).T
это тип класса с предоставленным пользователем конструктором по умолчанию, этот конструктор вызывается.T
это тип класса с неявно определенным или= default
созданным конструктором по умолчанию, объект инициализируется нулем, а затем вызывается конструктор по умолчанию.T
-std::initializer_list
, возвращаемое значение - пустой такой список.T
это неклассовый тип - возвращаемые типы не могут быть массивами) возвращаемое значение инициализируется нулем.источник
{}
, который может быть или не быть значением-init.Это своего рода сокращение для нового экземпляра возвращаемого типа методов.
источник