使用 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;
所以我有两个问题:
- 为什么time_point的默认构造函数不是
noexcept
?我的意思是,据我了解它只包含一些整数表示自纪元以来时间的类型,如果我相信 cppreference ,默认构造函数应该为 0
- 为什么仅从默认构造函数中删除
noexcept
有效? 如果编译器说它生成了 MyClass()
而不是 MyClass() noexcept
因此删除它,它应该与 MyClass(MyClass const&)
相同,对吗?但是编译器允许我在没有抱怨的情况下进行复制...
- 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
默认构造函数(它 应该 已经提供),那么它也可以在您的示例中工作。
我有一些这样的代码
#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&)
相同,对吗?但是编译器允许我在没有抱怨的情况下进行复制...
- 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
默认构造函数(它 应该 已经提供),那么它也可以在您的示例中工作。