“return {}”语句在 C++11 中是什么意思?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/39487065/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-28 14:50:08  来源:igfitidea点击:

What does "return {}" statement mean in C++11?

c++c++11returnreturn-valuelist-initialization

提问by Pedia

What does the statement

声明是什么

return {};

in C++11 indicate, and when to use it instead of (say)

在 C++11 中指示,以及何时使用它而不是(说)

return NULL;

or

或者

return nullptr;

采纳答案by wasthishelpful

return {};indicates "return an object of the function's return type initialized with an empty list-initializer". The exact behaviour depends on the returned object's type.

return {};表示“返回一个用空列表初始化器初始化的函数返回类型的对象”。确切的行为取决于返回对象的类型。

From cppreference.com(because the OP is tagged C++11, I excluded the rules in C++14 and C++17; refer to the link for further details):

来自cppreference.com(因为 OP 被标记为 C++11,我排除了 C++14 和 C++17 中的规则;请参阅链接以获取更多详细信息):

  • If the braced-init-list is empty and T is a class type with a default constructor, value-initialization is performed.
  • Otherwise, if T is an aggregate type, aggregate initialization is performed.
  • Otherwise, if T is a specialization of std::initializer_list, the T object is direct-initialized or copy-initialized, depending on context, from the braced-init-list.
  • Otherwise, the constructors of T are considered, in two phases:

    • All constructors that take std::initializer_list as the only argument, or as the first argument if the remaining arguments have default values, are examined, and matched by overload resolution against a single argument of type std::initializer_list
    • If the previous stage does not produce a match, all constructors of T participate in overload resolution against the set of arguments that consists of the elements of the braced-init-list, with the restriction that only non-narrowing conversions are allowed. If this stage produces an explicit constructor as the best match for a copy-list-initialization, compilation fails (note, in simple copy-initialization, explicit constructors are not considered at all).
  • Otherwise (if T is not a class type), if the braced-init-list has only one element and either T isn't a reference type or is a reference type that is compatible with the type of the element, T is direct-initialized (in direct-list-initialization) or copy-initialized (in copy-list-initialization), except that narrowing conversions are not allowed.

  • Otherwise, if T is a reference type that isn't compatible with the type of the element. (this fails if the reference is a non-const lvalue reference)
  • Otherwise, if the braced-init-list has no elements, T is value-initialized.
  • 如果花括号初始化列表为空并且 T 是具有默认构造函数的类类型,则执行值初始化。
  • 否则,如果 T 是聚合类型,则执行聚合初始化。
  • 否则,若 T 是 std::initializer_list 的特化,则 T 对象根据上下文从花括号初始化器列表中直接初始化或复制初始化。
  • 否则,分两个阶段考虑 T 的构造函数:

    • 所有采用 std::initializer_list 作为唯一参数的构造函数,或者如果其余参数具有默认值,则作为第一个参数,都被检查,并通过重载决议与 std::initializer_list 类型的单个参数匹配
    • 如果前一阶段没有产生匹配,则 T 的所有构造函数都参与针对由花括号初始化列表的元素组成的参数集的重载决议,但限制是只允许非窄化转换。如果此阶段生成一个显式构造函数作为复制列表初始化的最佳匹配,则编译失败(注意,在简单复制初始化中,根本不考虑显式构造函数)。
  • 否则(如果 T 不是类类型),如果花括号初始化列表只有一个元素并且 T 不是引用类型或者是与元素类型兼容的引用类型,则 T 是直接-初始化(在直接列表初始化中)或复制初始化(在复制列表初始化中),除了不允许缩小转换。

  • 否则,如果 T 是与元素类型不兼容的引用类型。(如果引用是非常量左值引用,则失败)
  • 否则,如果花括号初始化列表没有元素,则 T 是值初始化的。

Before C++11, for a function returning a std::string, you would have written:

在 C++11 之前,对于返回 a 的函数std::string,您应该这样写:

std::string get_string() {
    return std::string();
}

Using the brace syntax in C++11, you don't need to repeat the type:

使用 C++11 中的大括号语法,不需要重复类型:

std::string get_string() {
    return {}; // an empty string is returned
}

return NULLand return nullptrshould be used when the function returns a pointer type:

return NULL并且return nullptr应该在函数返回指针类型时使用:

any_type* get_pointer() {
    return nullptr;
}

However, NULLis deprecated since C++11 because it is just an alias to an integer value (0), while nullptris a real pointer type:

但是,NULL自 C++11 起已被弃用,因为它只是整数值 (0) 的别名,nullptr而是真正的指针类型:

int get_int() {
    return NULL; // will compile, NULL is an integer
}

int get_int() {
    return nullptr; // error: nullptr is not an integer
}

回答by Richard Hodges

This is probably confusing:

这可能令人困惑:

int foo()
{
  return {};   // honestly, just return 0 - it's clearer
}

This is probably not:

这可能不是:

SomeObjectWithADefaultConstructor foo()
{
  return {};
  // equivalent to return SomeObjectWithADefaultConstructor {};
}

回答by M.M

return {};means that {}is the initializer for the return value. The return value is list-initialized with an empty list.

return {};意味着这{}返回值的初始化程序。返回值使用空列表进行列表初始化。



Here is some background on the return value, based on [stmt.return] in the C++ Standard:

以下是基于 C++ 标准中的 [stmt.return]的返回值的一些背景:

For a function that returns by value (i.e. the return type is not a reference and not void), there is a temporary object called the return value. This object is created by the returnstatement, and its initializers depend on what was in the return statement.

对于按值返回的函数(即返回类型不是引用而不是void),有一个称为返回值的临时对象。该对象由return语句创建,其初始值设定项取决于 return 语句中的内容。

The return value survives until the end of the full-expression in the code that called the function; if it has class type, then its destructor will run unless it has lifetime extended by the caller binding a reference directly to it.

返回值一直存在,直到调用函数的代码中的完整表达式结束;如果它有类类型,那么它的析构函数将运行,除非调用者将引用直接绑定到它来延长它的生命周期。

The return value can be initialized in two different ways:

返回值可以通过两种不同的方式初始化:

  • return some_expression;- the return value is copy-initializedfrom some_expression
  • return { possibly_empty_list };- the return value is list-initializedfrom the list.


Assuming Tis the function's return type, then note that return T{};is different to return {}: in the former, a temporary T{}is created, and then the return valueis copy-initialized from that temporary.

假设T是函数的返回类型,那么注意它return T{};不同于return {}:在前者中,T{}创建一个临时对象,然后从该临时对象复制初始化返回值

This will fail to compile if Thas no accessible copy/move-constructor, but return {};will succeed even if those constructors are not present. Accordingly, return T{};may show side-effects of the copy-constructor etc., although this is a copy elision context so it may not.

如果T没有可访问的复制/移动构造函数,这将无法编译,但return {};即使这些构造函数不存在也会成功。因此,return T{};可能会显示复制构造函数等的副作用,尽管这是一个复制省略上下文,因此可能不是。



Here's a brief recap of list-initializationin C++14 (N4140 [dcl.init.list]/3), where the initializer is an empty list:

以下是C++14 (N4140 [dcl.init.list]/3)中列表初始化的简要回顾,其中初始化程序是一个空列表:

  • If Tis an aggregate, then each member is initialized from its brace-or-equal-initializerif it had one, otherwise as if by {}(so apply these steps recursively).
  • If Tis a class type with a user-provided default constructor, that constructor is called.
  • If Tis a class type with an implicitly-defined, or = defaulted default constructor, the object is zero-initializedand then the default constructor is called.
  • If Tis a std::initializer_list, the return value is an empty such list.
  • Otherwise (i.e. Tis a non-class type -- return types cannot be arrays), the return value is zero-initialized.
  • 如果T是一个聚合,那么每个成员都从它的大括号或等号初始化器初始化,如果它有一个,否则就像通过{}(所以递归地应用这些步骤)。
  • 如果T是具有用户提供的默认构造函数的类类型,则调用该构造函数。
  • 如果T是具有隐式定义或= defaulted 默认构造函数的类类型,则对象被零初始化,然后调用默认构造函数。
  • 如果T是 a std::initializer_list,则返回值是一个空的此类列表。
  • 否则(即T是非类类型——返回类型不能是数组),返回值是零初始化的。

回答by Victor Mwenda

It's a sort of short hand for a new instance of the methods return type.

这是方法返回类型的新实例的一种简写。