4

对于相等可比类型,相关但比C++11 静态断言更神秘?——</p>

JF Bastien 的论文N4130 “Pad Thy Atomics!” 让我想到,如果我们要使用atomic<T>::compare_exchange_weak()whereT是类或结构类型,例如

struct Count {
    int strong_count;
    int weak_count;
};

那么我们真的想要静态断言两件事:

首先,这T实际上是无锁原子的:

template<class T>
static constexpr bool is_lockfree_atomic_v =
    std::atomic<T>::is_always_lock_free;

其次,这compare_exchange_weak将做我们想要的。召回(或来自 N4130)根据和compare_exchange_weak定义的。所以我们需要检查这些函数是否会做正确的事情:memcmpmemcpyT

template<class T>
static constexpr bool is_cmpxchgable_v =
    std::is_trivially_copyable_v<T> &&
    is_trivially_equality_comparable_v<T>;

is_trivially_copyable_v由 STL 提供。但是我们还is_trivially_equality_comparable_v没有——遗憾的是,我的理解是P0515 一致比较不建议提供。(P0515 是允许编译器检测等式运算符实际上是“微不足道的”的功能——它不是用户提供的,并且在这样那样的条件下被明确默认。但是,它没有引入任何新概念,例如“平凡可比”进入核心语言。)

我对“微不足道的可比性”特征的最佳尝试如下所示:

template<class T, class U>
static constexpr bool is_equality_comparable_with_v =
    requires(std::declval<T>() == std::declval<U>());

template<class T>
static constexpr bool is_equality_comparable_v =
    is_equality_comparable_with_v<T, U>;

template<class T>
static constexpr bool is_trivially_equality_comparable_v =
    is_equality_comparable_v<T> &&
    std::has_unique_object_representations_v<T>;

但是,此定义依赖于std:: has_unique_object_representations_v, [EDIT:它具有未定义的行为,其值与 ] 的行为无关,operator==T它不是标量类型时。而且我强烈怀疑实际上 has_unique_object_representations_v会为结构类型(例如我的原始Count类型)返回垃圾。

struct Yes { int a; int b; };
struct No { short a; int b; };
using Yes2 = std::tuple<int, int>;
struct No2 { int a; int b; bool operator==(const No2&) { return true; }};
  • Clang/libc++ 还没有实现has_unique_object_representations
  • MSVC 尚未实现has_unique_object_representations,AFAIK。
  • GCC/libstdc++ 说那个has_unique_object_representations_v<Yes>,甚至正确地报告那个not has_unique_object_representations_v<No>,但是错误地报告那个not has_unique_object_representations_v<Yes2>和那个has_unique_object_representations_v<No2>

所以我的问题是,(1)有没有更好的方法来测试“琐碎的可比性”?is_trivially_equality_comparable(2) 如果 P0515 进入 C++20 的标准,在(is_trivially_less_than_comparable等等)提案的方向上是否有任何进展?(3) 应该有吗?

4

1 回答 1

4

我想你想要has_padding_bits。p0528 详细解释了原因。简而言之,您完全正确,memcpy并且memcmp

杰克逊维尔会议前的会议上将有一份更新的论文。

2018 年年中更新

标准委员会决定使用 p0528 朝另一个方向发展,而是使用填充位 Just Work 制作 cmpxchg 类型。has_padding_bits对于 p0528 想要解决的问题,不会有任何问题。

目前你的问题没有很好的答案:-)

于 2017-12-10T22:26:23.307 回答