繁体   English   中英

为什么 C++20 不使用 `requires` 来限制原子的 T<t> ?</t>

[英]Why C++20 doesn't use `requires` to restrict the T for atomic<T>?

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

[atomics.types.generic]/1

如果有以下任何一项,则该程序是格式错误

(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> ,

或 (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。 在下面的答案中正确指出:

特别是对于std::atomic ,约束主模板根本不是一种选择,因为在 C++20 中添加了atomic<shared_ptr<T>>atomic<weak_ptr<T>>化。

有一个选项建议:

也许你可以做一些更奇特的事情(比如一个未定义和不受约束的主模板加上一个受约束的部分特化),但它增加的价值很少。

好吧,还有另一种选择,不需要未定义和不受约束的主模板,这仍然有点复杂,并且降低了这种用法的概念的价值和乐趣,但可能比未定义的基本模板更好:

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

四。 让我们避免任何要求实现必须符合库规范的任何特定技术的规范。

a) 让我们允许实现使用requires-clauseenable_ifconstexpr if或任何其他技术或技术组合来满足Constraints:规范。

b) 让我们允许实现使用static_assert和/或任何其他技术来满足Mandates:规范。

c) 让我们允许实现使用合同属性 [P0542R1] 和/或任何其他技术来满足期望:确保:规范。

d) 让我们认为在实现部分依赖于任何特定技术的用户代码是格式错误的,不需要诊断。

P1369中对此进行了扩展。

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

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

特别是对于std::atomic ,约束主模板根本不是一种选择,因为在 C++20 中添加了atomic<shared_ptr<T>>atomic<weak_ptr<T>>化。

也许你可以做一些更奇特的事情(比如一个未定义和不受约束的主模板加上一个受约束的部分特化),但它增加的价值很少。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM