新语法“ =默认”在C ++ 11中 [英] The new syntax "= default" in C++11

查看:100
本文介绍了新语法“ =默认”在C ++ 11中的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我不明白为什么要这么做:

I don't understand why would I ever do this:

struct S { 
    int a; 
    S(int aa) : a(aa) {} 
    S() = default; 
};

为什么不只说:

S() {} // instead of S() = default;

为什么要为此引入新的语法?

why bring in a new syntax for that?

推荐答案

默认的默认构造函数被专门定义为与用户定义的默认构造函数相同,没有初始化列表且空复合语句。

A defaulted default constructor is specifically defined as being the same as a user-defined default constructor with no initialization list and an empty compound statement.

§12.1/ 6 [class.ctor] 默认值且未定义为Delete的默认构造函数在用于创建对象的对象时隐式定义它的类类型,或者在其第一次声明后明确地默认为它的类型。隐式定义的默认构造函数执行该类的初始化集,该初始化集将由该类的用户编写的默认构造函数执行,而没有ctor-initializer(12.6.2)和空的复合语句。 [...]

§12.1/6 [class.ctor] A default constructor that is defaulted and not defined as deleted is implicitly defined when it is odr-used to create an object of its class type or when it is explicitly defaulted after its first declaration. The implicitly-defined default constructor performs the set of initializations of the class that would be performed by a user-written default constructor for that class with no ctor-initializer (12.6.2) and an empty compound-statement. [...]

但是,尽管两个构造函数的行为相同,但提供空实现确实会影响类的某些属性。提供一个用户定义的构造函数,即使它什么都不做,也使该类型不是 aggregate ,也不是琐碎。如果希望您的类是集合类型或平凡类型(或通过传递性,则为POD类型),则需要使用 = default

However, while both constructors will behave the same, providing an empty implementation does affect some properties of the class. Giving a user-defined constructor, even though it does nothing, makes the type not an aggregate and also not trivial. If you want your class to be an aggregate or a trivial type (or by transitivity, a POD type), then you need to use = default.


§8.5.1/ 1 [dcl.init.aggr] 聚合是没有用户提供的构造函数的数组或类。 ..]

§8.5.1/1 [dcl.init.aggr] An aggregate is an array or a class with no user-provided constructors, [and...]




§12.1/ 5 [class.ctor] A如果不是用户提供的默认构造函数,并且[[]]

§12.1/5 [class.ctor] A default constructor is trivial if it is not user-provided and [...]

§9/ 6 [class] ,则默认的构造函数是琐碎的一个普通的默认构造函数和[...]

§9/6 [class] A trivial class is a class that has a trivial default constructor and [...]

演示:

#include <type_traits>

struct X {
    X() = default;
};

struct Y {
    Y() { };
};

int main() {
    static_assert(std::is_trivial<X>::value, "X should be trivial");
    static_assert(std::is_pod<X>::value, "X should be POD");
    
    static_assert(!std::is_trivial<Y>::value, "Y should not be trivial");
    static_assert(!std::is_pod<Y>::value, "Y should not be POD");
}

另外,显式默认构造函数将使其成为 constexpr 如果隐式构造函数本来应该并且还将为其提供与隐式构造函数相同的异常规范。在您给出的情况下,隐式构造函数将不会是 constexpr (因为它将使数据成员保持未初始化状态),并且也将具有一个空的异常规范,因此没有区别。但是可以,在通常情况下,您可以手动指定 constexpr 和异常说明以匹配隐式构造函数。

Additionally, explicitly defaulting a constructor will make it constexpr if the implicit constructor would have been and will also give it the same exception specification that the implicit constructor would have had. In the case you've given, the implicit constructor would not have been constexpr (because it would leave a data member uninitialized) and it would also have an empty exception specification, so there is no difference. But yes, in the general case you could manually specify constexpr and the exception specification to match the implicit constructor.

使用 = default 确实带来了一些统一性,因为它也可以与复制/移动构造函数和析构函数一起使用。例如,空副本构造函数将与默认的副本构造函数(将对其成员执行成员方式的复制)不同。对每个特殊成员函数统一使用 =默认值(或 =删除)语法可使代码更易于阅读通过明确说明您的意图。

Using = default does bring some uniformity, because it can also be used with copy/move constructors and destructors. An empty copy constructor, for example, will not do the same as a defaulted copy constructor (which will perform member-wise copy of its members). Using the = default (or = delete) syntax uniformly for each of these special member functions makes your code easier to read by explicitly stating your intent.

这篇关于新语法“ =默认”在C ++ 11中的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆