簡體   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