对于相等可比类型,相关但比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
定义的。所以我们需要检查这些函数是否会做正确的事情:memcmp
memcpy
T
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) 应该有吗?