零初始化的 std::atomic<T*> 保证等同于 nullptr 初始化的 std::T* 保证?
Is a zero initialized std::atomic<T*> guaranteed equivalent to one initialized with nullptr?
给定foo.cpp
:
#include <atomic>
namespace {
std::atomic<int*> gets_zero_init;
std::atomic<int*> gets_nullptr{nullptr};
}
我相信gets_zero_init
是零初始化的,并且它的初始化在零初始化之后完成。我也相信gets_nullptr
最终会用nullptr
初始化,我也相当相信gets_nullptr
的初始化在零初始化后不会完成,因为std::is_trivially_constructible<decltype(gets_nullptr), int*>::value
是false
(至少,它在我的编译器上)。然而,我有点不清楚gets_nullptr
是在常量初始化、静态初始化还是动态初始化之后完全初始化的。是哪一个?
此外,为了便于论证,我有兴趣确保感兴趣的对象在零初始化后完全初始化,并且不需要任何进一步的初始化,所以我采用gets_zero_init
方法。由于零初始化,嵌入在gets_zero_init
中的指针将保持全零位模式。
是否保证全零位模式等同于nullptr
?换句话说,如果我想要gets_nullptr
的语义,我可以依靠gets_zero_init
的零初始化来提供吗?
我想我已经想通了。
首先,我的帖子有一个错误。我没有意识到零初始化和常量初始化只是静态初始化的不同形式。你得到一个或另一个,而不是一个然后另一个。所以,忽略这一点误解。
我相信gets_zero_init
和gets_nullptr
都得到了静态初始化。第一个得到零初始化,有点明显。第二个得到恒定的初始化,因为:
- 采用T的std::atomic构造函数是constexpr
gets_nullptr
构造函数的自变量是一个常量表达式
换句话说,gets_zero_init
和gets_nullptr
都有静态初始化,因此后一种是更好的选择,因为它不依赖于假设全零位模式等效于nullptr。
相关文章:
- 在main()之外初始化std::vector会导致性能下降(多线程)
- 使用通用值初始化 std::map,不重复
- 初始化 std::vector 替换为单大括号而不是双大括号
- 在构造函数中使用可变参数初始化 std::tuple
- 使用大括号初始化 std::vector 使用初始值设定项列表
- 为什么初始化 std::vector 时不能使用模板整数?
- 如何在构造函数参数中初始化"std::set"?
- 初始化 std::数组 of Eigen::Map
- 我可以列表初始化 std::vector 并完美转发元素吗?
- 在 C++20 之前和之后初始化 std::atomic
- C++初始化 std::function 时如何将占位符绑定到引用/引用参数?
- 如何初始化 std::向量的映射?
- 如何在构造函数初始值设定项列表中使用 n 个元素初始化 std::vector<std::time_t>
- 使用范围库初始化 std::vector
- 如何在类的初始值设定项列表中初始化 std::array,而不对数组的大小进行硬编码
- 我是否需要在构造函数中显式初始化 std::unique_ptr?
- 如何使用派生类类型数据初始化 std::shared_ptr?
- 为什么我必须在初始化 std::array<SomeStruct, size> 时指定每个项目的类型C++
- 根据指针条件初始化std::vector
- 正在使用unique_ptr初始化std::vector