This page is a snapshot from the LWG issues list, see the Library Active Issues List for more information and the meaning of C++20 status.

### 3354. `has_strong_structural_equality` has a meaningless definition

Section: 21.3.5.4 [meta.unary.prop], 17.3.2 [version.syn] Status: C++20 Submitter: Daniel Krügler Opened: 2019-12-08 Last modified: 2021-02-25

Priority: 1

View other active issues in [meta.unary.prop].

View all other issues in [meta.unary.prop].

View all issues with C++20 status.

Discussion:

After the Belfast 2019 meeting with the acceptance of P1907R1 the core language term "strong structural equality" has been removed and instead a more general definition of a "structural type" has been introduced that is suitable to be used as non-type template parameter. These changes have caused the current definition of the `has_strong_structural_equality` type trait (which had originally been introduced by P1614R2 during the Cologne 2019 meeting) to become meaningless since it is currently defined as follows:

> The type `T` has strong structural equality (11.10.1 [class.compare.default]).

Besides the now undefined term "strong structural equality", the reference to 11.10.1 [class.compare.default] doesn't make sense anymore, assuming that the trait definition is supposed to refer now to a type that can be used as non-type template parameter.

During library reflector discussions several informal naming suggestions has been mentioned, such as `is_structural[_type]`, `can_be_nttp`, `is_nontype_template_parameter_type`.

Albeit `is_structural_type` would come very near to the current core terminology, core experts have argued that the term "structural type" should be considered as a "core-internal" term that may easily be replaced post-C++20.

In addition to that definition and naming question of that type trait it should be discussed whether there should exist a specific feature macro for just this type trait, similar to the reason why we introduced the `__cpp_lib_has_unique_object_representations` test macro for the `has_unique_object_representations` type trait while voting in P0258R2. The submitter of this issue believes that such a feature macro should be added and given that its final definition should be related to the date of the acceptance of this issue (and should not be related to any historically accepted papers such as P1614R2).

[2020-01 Priority set to 1 and questions to LEWG after review on the reflector.]

Previous resolution [SUPERSEDED]:

> This wording is relative to N4842.

> 1. Modify 17.3.2 [version.syn], header `<version>` synopsis, as indicated (The symbolic `??????L` represents the date to be defined by the project editor):

>    >     […]
>    >     #define __cpp_lib_is_swappable               201603L // also in <type_traits>
>    >     #define __cpp_lib_is_template_parameter_type ??????L // also in <type_traits>
>    >     #define __cpp_lib_jthread                    201911L // also in <stop_token>, <thread>
>    >     […]

> 2. Modify 21.3.3 [meta.type.synop], header `<type_traits>` synopsis, as indicated:

>    >     […]
>    >     template<class T> struct has_unique_object_representations;

>    >     template<class T> struct has_strong_structural_equalityis_template_parameter_type;

>    >     // 21.3.6 [meta.unary.prop.query], type property queries
>    >     […]
>    >     template<class T>
>    >       inline constexpr bool has_unique_object_representations_v
>    >         = has_unique_object_representations<T>::value;

>    >     template<class T>
>    >       inline constexpr bool has_strong_structural_equality_vis_template_parameter_type_v
>    >         = has_strong_structural_equalityis_template_parameter_type<T>::value;

>    >     // 21.3.6 [meta.unary.prop.query], type property queries
>    >     […]

> 3. Modify 21.3.3 [meta.type.synop], Table 47 ([tab:meta.unary.prop]) — "Type property predicates" — as indicated:

>    > Table 47: Type property predicates [tab:meta.unary.prop]
>    > Template | Condition | Preconditions
>    > --- | --- | ---
>    > `…`
>    > `template<class T> struct has_strong_structural_equalityis_template_parameter_type;` | The type `T` has strong structural equality (11.10.1 [class.compare.default]) can be used as non-type template-parameter (13.2 [temp.param]). | `T` shall be a complete type, cv `void`, or an array of unknown bound. If `T` is a class type, `T` shall be a complete type.
>    > `…`

[2020-02, Prague]

LEWG looked at this and suggested to remove the existing trait `has_strong_structural_equality` for now until someone demonstrates which usecases exist that would justify its existence.

[2020-02-13, Prague]

Set to Immediate.

Proposed resolution:

This wording is relative to N4849.

1. Modify 21.3.3 [meta.type.synop], header `<type_traits>` synopsis, as indicated:

   >     […]
   >     template<class T> struct has_unique_object_representations;

   >     template<class T> struct has_strong_structural_equality;

   >     // 21.3.6 [meta.unary.prop.query], type property queries
   >     […]
   >     template<class T>
   >       inline constexpr bool has_unique_object_representations_v
   >         = has_unique_object_representations<T>::value;

   >     template<class T>
   >       inline constexpr bool has_strong_structural_equality_v
   >         = has_strong_structural_equality<T>::value;

   >     // 21.3.6 [meta.unary.prop.query], type property queries
   >     […]

2. Modify 21.3.3 [meta.type.synop], Table 47 ([tab:meta.unary.prop]) — "Type property predicates" — as indicated:

   > Table 47: Type property predicates [tab:meta.unary.prop]
   > Template | Condition | Preconditions
   > --- | --- | ---
   > `…`
   > `template<class T> struct has_strong_structural_equality;` | The type `T` has strong structural equality (11.10.1 [class.compare.default]). | `T` shall be a complete type, cv `void`, or an array of unknown bound.