C ++ 11中的新关键字= default [英] The new keyword =default in C++11

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

问题描述

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

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 keyword 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] 默认构造函数是默认构造函数,未定义为已删除构造函数,创建一个类类型的对象,或者在第一个声明之后显式默认的对象。隐式定义的默认构造函数执行类的初始化集合,该类将由用户编写的没有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. [...]

然而,虽然两个构造函数的行为相同,但提供一个空的实现会影响类的一些属性。提供用户定义的构造函数,即使它什么也不做,使得类型不是聚集,也不是琐碎。如果你希望你的类是一个聚合或一个简单的类型(或传递性,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] 聚合是一个没有用户提供的构造函数的数组或类,[and ...]

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






/ 5 [class.ctor]如果不是用户提供的,默认构造函数是微不足道的。[...]

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

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 确实带来一些一致性,因为它也可以用于复制/移动构造函数和析构函数。例如,一个空的拷贝构造函数将不会像默认的拷贝构造函数一样(它将执行其成员的成员方式的拷贝)。对每个特殊的成员函数使用 = default (或 = delete )语法使得代码更容易阅读通过明确说明您的意图。

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中的新关键字= default的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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