使用 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 我的意思是,据我所知,它只包含一个表示自纪元以来时间的某种类型的整数,它应该如果我相信 cppreference
  • 认构造函数为 0
  • 为什么只从认构造函数删除 noexcept 有效?如果编译器说它生成MyClass() 而不是 MyClass() noexcept 并因此删除它, MyClass(MyClass const&) 应该是一样的,对吧?但是编译器让我在没有抱怨的情况下进行复制......

解决方法

  • 为什么 time_point 的默认构造函数不是 noexcept?

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

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

  • 为什么只从默认构造函数中删除 noexcept 会起作用?

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

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

相关问答

Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其...
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。...
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbc...