简体   繁体   English

C ++ 11中“return {}”语句的含义是什么?

[英]What does “return {}” statement mean in C++11?

What does the statement 这句话是什么?

return {};

in C++11 indicate, and when to use it instead of (say) 在C ++ 11中指出,何时使用它而不是(比如说)

return NULL;

or 要么

return nullptr;

return {}; indicates "return an object of the function's return type initialized with an empty list-initializer ". 表示“返回使用空list-initializer初始化的函数返回类型的对象”。 The exact behaviour depends on the returned object's type. 确切的行为取决于返回的对象的类型。

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. 如果braced-init-list为空且T是具有默认构造函数的类类型,则执行值初始化。
  • Otherwise, if T is an aggregate type, aggregate initialization is performed. 否则,如果T是聚合类型,则执行聚合初始化。
  • 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. 否则,如果T是std :: initializer_list的特化,则根据上下文,从braced-init-list直接初始化或复制初始化T对象。
  • Otherwise, the constructors of T are considered, in two phases: 否则,T的构造函数分为两个阶段:

    • 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 将std :: initializer_list作为唯一参数的所有构造函数,或作为第一个参数,如果其余参数具有默认值,将检查所有构造函数,并通过重载决策与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. 如果前一个阶段没有产生匹配,则T的所有构造函数都参与对由braced-init-list元素组成的参数集的重载解析,并限制只允许非缩小转换。 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. 否则(如果T不是类类型),如果braced-init-list只有一个元素,并且T不是引用类型或者是与元素类型兼容的引用类型,则T是直接的 - 初始化(在直接列表初始化中)或复制初始化(在复制列表初始化中),但不允许缩小转换。

  • Otherwise, if T is a reference type that isn't compatible with the type of the element. 否则,如果T是与元素类型不兼容的引用类型。 (this fails if the reference is a non-const lvalue reference) (如果引用是非常量左值引用,则会失败)
  • Otherwise, if the braced-init-list has no elements, T is value-initialized. 否则,如果braced-init-list没有元素,则T是值初始化的。

Before C++11, for a function returning a std::string , you would have written: 在C ++ 11之前,对于返回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 NULL and return nullptr should be used when the function returns a pointer type: 当函数返回指针类型时,应该使用return NULLreturn nullptr

any_type* get_pointer() {
    return nullptr;
}

However, NULL is deprecated since C++11 because it is just an alias to an integer value (0), while nullptr is a real pointer type: 但是,自C ++ 11以来不推荐使用NULL因为它只是整数值(0)的别名,而nullptr是一个真正的指针类型:

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

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

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 {};
}

return {}; means that {} is the initializer for the return value . 表示{}返回值的初始值设定项 The return value is list-initialized with an empty list. 返回值使用空列表进行列表初始化。


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 (ie the return type is not a reference and not void ), there is a temporary object called the return value . 对于按值返回的函数(即返回类型不是引用而不是void ),有一个名为返回值的临时对象。 This object is created by the return statement, and its initializers depend on what was in the return statement. 此对象由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: 返回值可以通过两种不同的方式初始化:


Assuming T is the function's return type, then note that return T{}; 假设T是函数的返回类型,则注意return T{}; is different to return {} : in the former, a temporary T{} is created, and then the return value is copy-initialized from that temporary. return {}不同:在前者中,创建临时T{} ,然后从该临时复制初始化返回值

This will fail to compile if T has no accessible copy/move-constructor, but return {}; 如果T没有可访问的copy / move-constructor,则无法编译,但return {}; will succeed even if those constructors are not present. 即使那些构造函数不存在,也会成功。 Accordingly, return T{}; 因此, return T{}; may show side-effects of the copy-constructor etc., although this is a copy elision context so it may not. 可能会显示复制构造函数等的副作用,虽然这是复制省略,因此可能不会。


Here's a brief recap of list-initialization in C++14 (N4140 [dcl.init.list]/3), where the initializer is an empty list: 下面简要回顾一下C ++ 14中的列表初始化 (N4140 [dcl.init.list] / 3),其中初始化器是一个空列表:

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

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 什么是`类模板示例<int> ;` 语句在 C++11 中是什么意思? - What does `class template Example<int>;` statement mean with C++11? 这个C ++ / C ++ 11构造意味着什么? - What does this C++ / C++11 construction mean? T&amp;&amp;(双与号)在 C++11 中是什么意思? - What does T&& (double ampersand) mean in C++11? extern模板是c ++ 11扩展的意思是什么? - What does extern templates are a c++11 extension mean? 这句话在C ++ 11标准的第3.2.2段中意味着什么? - What does this sentence mean in paragraph §3.2/2 of the C++11 Standard? 在C ++ 11中thread_local是什么意思? - What does the thread_local mean in C++11? C ++ 11标准中的哪一个子句允许我消除下面`A :: operator-()`中的`return`语句中的`A`? - What clause in the C++11 Standard does allow me to eliminate the `A` in the `return` statement in the `A::operator-()` below? 这个陈述在C ++ 11标准中的含义是什么? - What is the meaning of this statement in the C++11 Standard? 自动更改意义在C ++ 11中; 请删除它是什么意思? - auto changes meaning in C++11; please remove it what does this mean? C ++ 11:原子变量:lock_free属性:这是什么意思? - C++11 : Atomic variable : lock_free property : What does it mean?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM