C++ Logo

std-proposals

Advanced search

Re: Are constrained type barred from std:: implementations?

From: Lénárd Szolnoki <cpp_at_[hidden]>
Date: Fri, 20 Aug 2021 21:52:11 +0100
On Fri, 20 Aug 2021 10:41:54 +0200
DBJ via Std-Proposals <std-proposals_at_[hidden]> wrote:

> I can see (for example) static_assert being used in basic_stringview
> to constrain the instantiation of it. Not the type definition.
>
> Thus I am wondering what was/is wrong with using C++20 require, for
> example?
>
> I was told standard specifically allows for wrong types to be
> defined; like eg tuple<void> or basic_stringview<void ***> ...
>
> Is the following synopsis thus not following the standard?
>
> #include <string>
> #include <type_traits>
>
> namespace {
> using namespace std;
>
> template <class _Elem, class _Traits>
> #if __cplusplus >= 202002L
> // C++20 (and later) code
> requires // requires-clause (ad-hoc constraint)
> is_same_v<_Elem, typename _Traits::char_type> &&
> (!is_array_v<_Elem>)&&is_trivial_v<_Elem>&&
> is_standard_layout_v<_Elem> #endif
> class basic_string_view { // wrapper for any kind of contiguous
> character
> // buffer
> public:
> #if __cplusplus < 202002L
> // apparently standard was/is barring std:: types to be constrained?
> // ditto this is instantiation constraint
> // as present in MS STL today
> static_assert(is_same_v<_Elem, typename _Traits::char_type>,
> "Bad char_traits for basic_string_view; "
> "N4659 24.4.2 [string.view.template]/1 \"the type "
> "traits::char_type shall name the same type as
> charT.\"");
>
> static_assert(!is_array_v<_Elem> && is_trivial_v<_Elem> &&
> is_standard_layout_v<_Elem>,
> "The character type of basic_string_view must be a
> non-array "
> "trivial standard-layout type. See N4861 "
> "[strings.general]/1.");
> #endif
> };
>
> using ok_sv = basic_string_view<char, std::char_traits<char> >;
>
> } // namespace
>
> *https://godbolt.org/z/44cWrqqcs <https://godbolt.org/z/44cWrqqcs>*

There is an observable difference between constraining the primary class
template and static_assert within the body of the class template
definition, that is in the latter case the types `function<int>*`,
`basic_string_view<void***>*`, ... can be formed or in general these
types can be used as incomplete types so that the corresponding class
template specializations are not instantiated.

https://godbolt.org/z/xrfY9j64e

In the standard the synopsis is not constrained, and I'm not sure that
implementers are allowed to add that to primary class templates, even
though it would probably make sense.

Cheers,
Lénárd

Received on 2021-08-20 15:52:20