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

时光怂恿深爱的人放手 提交于 2020-08-07 18:27:41

问题


A generic std::atomic<T> is required to have a T that is Copy Constructible and Copy Assignable:

[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>

is false.

Above is not new to C++20. Compilers may use static_assert to issue an error for a non-conforming T.

However, C++20 could use formal constraints with the requires syntax to formally require the above as part of the type, e.g. something like:

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 { ... };

Is there a reason why C++20 refrained from using formal constraints for this purpose?


EDIT: @T.C. points out correctly, in an answer below:

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.

with an option suggesting that:

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

Well, there is another option, without the need for an undefined and unconstrained primary template, which is still a bit complex and reduces the value and fun in going with concepts for this usage, but probably better than an undefined base template:

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

Code: https://godbolt.org/z/JaCu78


回答1:


The library specification deliberately avoids using any particular technology to achieve its goals 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.

Which is expanded upon in P1369.

The goal is to avoid tying the specification of the library to any particular implementation of it. There are cases where you do need to do this - many of the Ranges things do require concepts to work, so they are specified in this way - but for the most part, you don't.

For the user, the important part is the mandated requirements on T. It's not important how those requirements are enforced. It could be a concept, it could be a static_assert, it could be some compiler intrisic, whatever.




回答2:


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.



来源:https://stackoverflow.com/questions/62154178/why-c20-doesnt-use-requires-to-restrict-the-t-for-atomict

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!