我写了一个is_incrementable这样的特征:
#include <type_traits>
template <typename T, typename = void>
struct is_incrementable : std::false_type {};
template <typename T>
struct is_incrementable<T, std::void_t<decltype(++std::declval<T&>())>>
: std::true_type {};
template <typename T>
constexpr bool is_incrementable_v = is_incrementable<T>::value;
Run Code Online (Sandbox Code Playgroud)
当我把它应用到bool与-std=c++17上铛,它返回true:
// This compiles
static_assert(is_incrementable_v<bool>, "");
Run Code Online (Sandbox Code Playgroud)
但是bool在c ++ 17下不允许递增.的确,如果我尝试这样做,我会收到一个错误:
bool b = false;
++b;
Run Code Online (Sandbox Code Playgroud)
结果是:
error: ISO C++17 does not allow incrementing expression of type bool [-Wincrement-bool]
Run Code Online (Sandbox Code Playgroud)
bool当编译器明确不允许时,为什么SFINAE报告可递增?
编译器浏览器:https://godbolt.org/g/DDFYBf
考虑这个程序:
-- Initially --
std::atomic<int> x{0};
int y{0};
-- Thread 1 --
y = 1; // A
x.store(1, std::memory_order_release); // B
x.store(3, std::memory_order_relaxed); // C
-- Thread 2 --
if (x.load(std::memory_order_acquire) == 3) // D
print(y); // E
Run Code Online (Sandbox Code Playgroud)
在 C++11 内存模型下,如果程序打印任何内容,则它会打印 1。
在 C++20 内存模型中,释放顺序已更改以排除由同一线程执行的写入。这对这个程序有何影响?现在可以进行数据竞争并打印 或0吗1?
这段代码出现在P0982R1: Weaken Release Sequences中,我相信这篇论文导致了 C++20 中发布序列定义的更改。在该特定示例中,有第三个线程进行存储,x该存储以违反直觉的方式中断了释放顺序。这激发了削弱发布顺序定义的需要。
通过阅读该论文,我的理解是,随着C++20的变化,C将不再构成以B为首的发布序列的一部分,因为C不是读-修改-写操作。因此C不与D同步。因此A和E之间不存在happens-before关系。
由于 B 和 C 存储到同一个原子变量,并且所有线程必须就该变量的修改顺序达成一致,因此 C++20 内存模型是否允许我们推断 A 是否发生在 E 之前?