为什么不能默认构造std::chrono time_point成员变量的std::atomic?

3
我有一个原子包装了chrono time_point值。对于我来说,time_point的默认构造很好,所以我希望不需要明确设置它。然而,在gcc中,如果不明确设置默认值,我会得到编译器错误。这是一个最小的示例:
#include <atomic>
#include <chrono>

struct A
{
    using TimePoint = std::chrono::system_clock::time_point;
    std::atomic<TimePoint> point;
};

int 
main()
{
    A a;
    return 0;
}

这是错误信息:

<source>: In function 'int main()':
<source>:13:7: error: use of deleted function 'A::A()'
     A a;
       ^
<source>:6:5: note: 'A::A()' is implicitly deleted because the default definition would be ill-formed:
     A() = default;
     ^
<source>:6:5: error: use of deleted function 'constexpr std::atomic<_Tp>::atomic() [with _Tp = std::chrono::time_point<std::chrono::_V2::system_clock, std::chrono::duration<long int, std::ratio<1, 1000000000> > >]'
In file included from <source>:1:
/opt/compiler-explorer/gcc-8.3.0/include/c++/8.3.0/atomic:194:7: note: 'constexpr std::atomic<_Tp>::atomic() noexcept [with _Tp = std::chrono::time_point<std::chrono::_V2::system_clock, std::chrono::duration<long int, std::ratio<1, 1000000000> > >]' is implicitly deleted because its exception-specification does not match the implicit exception-specification ''
       atomic() noexcept = default;
       ^~~~~~
Compiler returned: 1

这里是一个godbolt链接: https://godbolt.org/z/YocxGd 我可以通过显式添加默认初始化来解决这个问题(https://godbolt.org/z/8z5WqW)。
std::atomic<TimePoint> point{TimePoint{}};

但我觉得这样做很傻。我不明白哪里出了问题。我注意到从10.x开始的clang和gcc都不会抱怨隐式默认值。这只是旧版本gcc的编译器错误吗?还是我应该有更优雅的方式来处理这个问题,而不是显式地初始化time_point?


请注意,std::atomic<std::chrono::high_resolution_clock::time_point> 无法编译 引用了相同的错误信息,但是询问的是(并获得了)在线程之间共享 time_point 的机制。我没有这个问题。我特别询问为什么隐式默认构造的值不起作用,而显式默认构造的值却可以工作。
1个回答

3
很好的回答@Nicol - 但我会选择一个libstdc++的bug。 以下代码:
#include <atomic>

struct A {
    A() {}
};

int main () {
    std::atomic<A> a;
}

在gcc 8.3/9.x上会出现类似的错误,但在gcc 10.x上(使用-std=c++17)没有错误编译。

clang8 + libstdc++ 8.3也会失败。

clang + libc++ 可以无错编译。


3
根据我在回答中所述的条件,我无法使用自己的类重新现该错误。也就是说,一个包含非noexcept默认构造成员的noexcept = default类型似乎可以正常进行默认初始化。因此我猜测问题可能出在这里。 - Nicol Bolas

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接