使用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;

所以我有两个问题:

  • 为什么time_point的默认构造函数不是noexcept我的意思是,据我所知,它只包含一个某种类型的整数,表示自epoch以来的时间,如果我相信cpprreference,它应该是默认构造函数的0
  • 为什么仅从默认构造函数中删除noexcept有效如果编译器说它生成了MyClass()而不是MyClass() noexcept,并因此删除了它,那么MyClass(MyClass const&)应该也是一样的,对吧?但编译器让我在这里复制而不抱怨
  • 为什么time_point的默认构造函数不是noexcept

noexcept第一次进入C++11中的标准时;过度应用";noexcept添加到标准中比删除要容易得多。在保守地应用时;有条件的";noexcept经常被回避。

我希望看到";有条件的";CCD_ 10应用于CCD_。对于time_point默认构造函数,noexcept将取决于rep是否是noexcept默认可构造的。rep不一定是整数。它可能是一个具有抛出默认构造函数的类类型。但特殊化steady_clock::time_point将始终是noexcept,因为它的rep需要积分的。

  • 为什么只从默认构造函数中删除noexcept有效

因为time_point有一个用户声明的默认构造函数,但有一个编译器提供的复制构造函数。这是编译器提供的特殊成员可以如此之多"的一个例子;更聪明";而不是用户声明的。

编译器提供的CCD_ 21的复制构造函数实际上已经具有一个"0";有条件的";CCD_ 22。你可以通过写更少的代码免费获得这些。如果time_point默认构造函数是编译器提供的(它应该是(,那么它在您的示例中也可以工作。

最新更新