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

问题描述 投票:1回答:2

一个通用的 std::atomic<T> 是需要有一个 T 也就是 复制可建构复制可转让:

[atomics.type.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不使用形式化的... 限制 为了这个目的?


EDIT: @T. C. 在下面的回答中指出了正确的观点。

对于 std::atomic 特别是,考虑到主模板的重要性,约束主模板根本不是一个选项。atomic<shared_ptr<T>>atomic<weak_ptr<T>> 在C++20中增加的专门化。

与一个选项建议。

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

好吧,还有另一个选项,不需要使用 一个未定义和未限制的主模板。,这还是有点复杂,降低了这种用法的概念价值和乐趣,但可能比一个未定义的基础模板要好。

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.orgzJaCu78

c++ atomic c++20 c++-concepts
2个回答
8
投票

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

四. 让我们避免任何规范要求任何特定的技术,通过这些技术实现必须遵守库规范。

a) 让我们允许一个实现使用一个 要求条款,一个 enable_if, a constexpr if或任何其他技术或技术组合,以满足以下要求 限制条件。 规范。

b) 让我们允许一个实现使用 static_assert 或任何其他技术来满足 任务。 规格。

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

d)我们认为用户代码在实现部分依赖任何特定技术的情况下都是不合格的,不需要诊断。

这一点在 P1369.

我们的目标是避免捆绑 规格 馆的任何一个特定的 实施 的。在有些情况下,你确实需要这样做--许多Ranges的东西确实需要概念来工作,所以它们是以这种方式指定的--但在大多数情况下,你不需要这样做。

对于用户来说,重要的部分是对下面的规定要求。T. 这不重要 如何 这些要求得到执行。这可能是一个概念,也可能是一种新的概念。static_assert这可能是编译器的内在因素,不管是什么。


2
投票

对于 std::atomic 特别是,考虑到主模板的重要性,约束主模板根本不是一个选项。atomic<shared_ptr<T>>atomic<weak_ptr<T>> C++20中添加的特殊化。

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

© www.soinside.com 2019 - 2024. All rights reserved.