使用 std::chrono::time_point 隐式删除特殊函数

Implicitly deleted special functions with std::chrono::time_point

我有一些这样的代码

#include <chrono>
using std::chrono::steady_clock;
using std::chrono::time_point;

class MyClass
{
public:
    MyClass() noexcept = default;
    MyClass(MyClass const&) noexcept = default;
    MyClass(MyClass&&) noexcept = default;
    MyClass& operator=(MyClass const&) noexcept = default;
    MyClass& operator=(MyClass&&) noexcept = default;
private:
    time_point<steady_clock> timestamp; 
};

int main() {
    MyClass myObject;
    MyClass myOtherObject(myObject);
    return 0;
}

尝试编译它会导致

prog.cpp: In function ‘int main()’:
prog.cpp:18:10: error: use of deleted function ‘constexpr MyClass::MyClass()’
  MyClass myObject;
          ^~~~~~~~
prog.cpp:8:5: note: ‘constexpr MyClass::MyClass() noexcept’ is implicitly deleted because
its exception-specification does not match the implicit exception-specification ‘’
     MyClass() noexcept = default;

但是,如果我删除默认构造函数的 noexcept 说明符,则可以正常编译:

MyClass() = default;
MyClass(MyClass const&) noexcept = default;
MyClass(MyClass&&) noexcept = default;
MyClass& operator=(MyClass const&) noexcept = default;
MyClass& operator=(MyClass&&) noexcept = default;

所以我有两个问题:

  • How come time_point's default constructor isn't noexcept?

noexcept 首次进入 C++11 标准时,委员会非常犹豫是否要“过度应用”它。 noexcept 添加到标准比删除要容易得多。在保守地应用它时,“有条件的”noexcept 经常被回避。

我希望看到“有条件的”noexcept 应用于 <chrono>。对于 time_point 默认构造函数,noexcept 将以 rep 是否为 noexcept 默认构造函数为条件。 rep 不必是整数。它可能是具有抛出默认构造函数的 class 类型。但是专业化 steady_clock::time_point 将始终是 noexcept 因为它 rep 需要积分。

  • Why does removing noexcept from only the default constructor work?

因为time_point has a user-declared default constructor but a compiler-supplied copy constructor。这是编译器提供的特殊成员如何比用户声明的成员“更聪明”的一个例子。

time_point 的编译器提供的复制构造函数实际上已经有一个“条件”noexcept。您可以通过编写更少的代码免费获得此功能。如果编译器提供了 time_point 默认构造函数(它 应该 已经提供),那么它也可以在您的示例中工作。