gpt4 book ai didi

c++ - std::chrono::duration::duration() 如何成为 constexpr?

转载 作者:IT老高 更新时间:2023-10-28 22:14:33 30 4
gpt4 key购买 nike

std::chrono::duration的默认构造函数定义如下:

constexpr duration() = default;

(例如,参见 cppreference.com 或 libstdc++ 源代码。)

但是,cppreference.com also says this关于 constexpr 构造函数:

A constexpr constructor must satisfy the following requirements:

...

every base class and every non-static member must be initialized, either in the constructors initialization list or by a member brace-or-equal initializer. In addition, every constructor involved must be a constexpr constructor and every clause of every brace-or-equal initializer must be a constant expression

如果我对默认构造函数感到困惑,cppreference.com seems to say使用 = default 产生的默认构造函数的定义与隐式默认构造函数没有区别。

然而,(大多数)持续时间的 rep 类型是裸整数类型。那么,duration 的显式 = default 默认构造函数不应该等同于

constexpr duration() {}

这当然会使 duration::rep 类型的整数成员变量未初始化?而且,事实上,duration 的标准行为难道不是默认构造的值 未初始化吗? (但我找不到明确说明这一点的引用资料。)

那么,如果 duration= default 构造函数未初始化非静态成员变量,它怎么能成为 constexpr 呢?我错过了什么?

最佳答案

7.1.5 constexpr 说明符 [dcl.constexpr] 说:

The definition of a constexpr constructor shall satisfy thefollowing requirements:

  • the class shall not have any virtual base classes;
  • for a defaulted copy/move constructor, the class shall not have a mutable subobject that is a variant member;
  • each of the parameter types shall be a literal type;
  • its function-body shall not be a function-try-block;

In addition, either its function-body shall be = delete, or it shallsatisfy the following requirements:

  • either its function-body shall be = default, or the compound-statement of its function-body shall satisfy the requirementsfor a function-body of a constexpr function;
  • every non-variant non-static data member and base class sub-object shall be initialized (12.6.2);
  • if the class is a union having variant members (9.5), exactly one of them shall be initialized;
  • if the class is a union-like class, but is not a union, for each of its anonymous union members having variant members, exactly one ofthem shall be initialized;
  • for a non-delegating constructor, every constructor selected to initialize non-static data members and base class sub-objects shall bea constexpr constructor;
  • for a delegating constructor, the target constructor shall be a constexpr constructor.

简而言之,只要满足上述其他要求,= default 就是 constexpr 默认构造函数的有效定义。

那么这如何与未初始化的构造一起工作?

没有。

例如:

constexpr seconds x1{};

上述工作并将x1初始化为0s。然而:

constexpr seconds x2;

error: default initialization of an object of const type 'const seconds'
(aka 'const duration<long long>') without a user-provided default
constructor
constexpr seconds x2;
^
{}
1 error generated.

所以要创建一个constexpr默认构造的duration,你必须零初始化它。 = default 实现允许使用 {} 进行零初始化。

完整的工作演示:

template <class Rep>
class my_duration
{
Rep rep_;
public:
constexpr my_duration() = default;
};


int
main()
{
constexpr my_duration<int> x{};
}

有趣的侧边栏

我在写这个答案的过程中学到了一些东西,并想分享:

我一直想知道为什么以下方法不起作用:

using Rep = int;

class my_duration
{
Rep rep_;
public:
constexpr my_duration() = default;
};


int
main()
{
constexpr my_duration x{};
}

error: defaulted definition of default constructor is not constexpr
constexpr my_duration() = default;
^

为什么将这个类设为非模板会破坏 constexpr 默认构造函数?!

(更新:现在可以用 C++20 编译)

然后我尝试了这个:

using Rep = int;

class my_duration
{
Rep rep_;
public:
my_duration() = default; // removed constexpr
};


int
main()
{
constexpr my_duration x{};
}

编译器又喜欢它了。

如果在这方面还没有 CWG 问题,那么可能应该有。这种行为似乎有点不一致。这可能只是因为我们(整个行业)仍在学习constexpr已在C++20中修复。

关于c++ - std::chrono::duration::duration() 如何成为 constexpr?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36342296/

30 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com