![](/img/trans.png)
[英]Can I use C++20 `std::atomic<T>::wait()` or `std::atomic_flag::wait()` in shared memory?
[英]Why C++20 doesn't use `requires` to restrict the T for atomic<T>?
通用std::atomic<T>
需要具有可復制構造和可復制分配的T
:
如果有以下任何一項,則該程序是格式錯誤的
(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
庫規范故意避免使用任何特定技術來實現其目標P0788 :
四。 讓我們避免任何要求實現必須符合庫規范的任何特定技術的規范。
a) 讓我們允許實現使用requires-clause 、
enable_if
、constexpr 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.