c++ - 为什么 C++20 不使用 `requires` 来限制 atomic<T> 的 T?

标签 c++ atomic c++20 c++-concepts

通用 std::atomic<T>需要有 T即可复制构造和可复制分配:

[atomics.types.generic]/1

The program is ill-formed if any of

(1.1) is_­trivially_­copyable_­v<T>,

(1.2) is_­copy_­constructible_­v<T>,

(1.3) is_­move_­constructible_­v<T>,

(1.4) is_­copy_­assignable_­v<T>,

or (1.5) is_­move_­assignable_­v<T>



false .

以上对 C++20 来说并不陌生。编译器可以使用 static_assert为不合格的 T 发出错误。

但是,C++20 可以使用带有 requires 的形式约束。正式要求上述内容作为类型一部分的语法,例如就像是:
template< class T > requires
    std::is_trivially_copyable_v<T> &&
    std::is_copy_constructible_v<T> &&
    std::is_move_constructible_v<T> &&
    std::is_copy_assignable_v<T> &&
    std::is_move_assignable_v<T>
struct atomic { ... };

C++20 是否有理由避免为此目的使用形式约束?

编辑: @T.C.正确指出,在下面的答案中:

For std::atomic in particular, constraining the primary template is simply not an option, given the atomic<shared_ptr<T>> and atomic<weak_ptr<T>> specializations that were added in C++20.



有一个选项建议:

Perhaps you can do something fancier (like an undefined and unconstrained primary template plus a constrained partial specialization), but it adds very little value.



嗯,还有另一种选择,不需要未定义和
不受约束的主模板,它仍然有点复杂,降低了使用此用法概念的值(value)和乐趣,但可能比未定义的基本模板更好:
template< class T > requires
    std::is_trivially_copyable_v<T> &&
    std::is_copy_constructible_v<T> &&
    std::is_move_constructible_v<T> &&
    std::is_copy_assignable_v<T> &&
    std::is_move_assignable_v<T>
    || std::same_as<T, std::shared_ptr<typename T::element_type>>
    || std::same_as<T, std::weak_ptr<typename T::element_type>>
struct atomic { ... };

template< class T >
struct atomic<std::shared_ptr<T>> { ... };

template< class T >
struct atomic<std::weak_ptr<T>> { ... };

// types of all other specializations are Copy Constructible and Copy Assignable

代码:https://godbolt.org/z/JaCu78

最佳答案

库规范故意避免使用任何特定技术来实现其目标 P0788 :

IV. Let’s avoid any specification that demands any particular technology by which implementations must comply with Library specifications.

a) Let’s permit an implementation to use a requires-clause, an enable_if, a constexpr if, or any other technology or combination of technologies to meet Constraints: specifications.

b) Let’s permit an implementation to use static_assert and/or any other technologies to meet Mandates: specifications.

c) Let’s permit an implementation to use Contracts attributes [P0542R1] and/or any other technologies to meet Expects: and Ensures: specifications.

d) Let’s consider user code that relies on any specific technology on the part of an implementation to be ill-formed, with no diagnostic required.



P1369 中对其进行了扩展.

目标是避免将库的规范与它的任何特定实现联系起来。在某些情况下,您确实需要这样做 - 许多范围的事情确实需要概念才能工作,因此它们以这种方式指定 - 但在大多数情况下,您不需要。

对于用户来说,重要的部分是对 T 的强制要求。 .如何执行这些要求并不重要。它可能是一个概念,也可能是一个 static_assert ,它可能是一些编译器内在的,无论如何。

关于c++ - 为什么 C++20 不使用 `requires` 来限制 atomic<T> 的 T?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/62154178/

相关文章:

c++ - 使用脚本在原子中使用 Armadillo

c++ - 这是一个 VC++2010 编译器错误吗?

C++,()运算符重载,它的工作是什么

c++ - 宽松的内存顺序效果是否可以延长到执行线程的生命周期之后?

跨越多个 Web 请求的 MongoDB 事务

c++ - 将约束应用于模板的三种方式有什么区别?

c++ - 从 constexpr 处的 std::views::split 获取最后一个元素

c++ - 在c++中将字符串变成变量真的不可能吗

multithreading - 使用原子交换实现原子增量?

c++ - std::is_constant_evaluated 时如何获取常量表达式?