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

### 2567. Specification of logical operator traits uses `BaseCharacteristic`, which is defined only for `UnaryTypeTraits` and `BinaryTypeTraits`

Section: 20.15.9 [meta.logical] Status: C++17 Submitter: Tim Song Opened: 2015-12-10 Last modified: 2017-07-30

Priority: 2

View all other issues in [meta.logical].

View all issues with C++17 status.

Discussion:

The specification of `conjunction` and `disjunction` uses the term `BaseCharacteristic`, which is problematic in several ways:

- That term is defined in 20.15.2 [meta.rqmts], but only for `UnaryTypeTraits` and `BinaryTypeTraits`. `conjunction` and `disjunction` seem to be neither.

- 20.15.2 [meta.rqmts] also requires the `BaseCharacteristic` for both `UnaryTypeTraits` and `BinaryTypeTraits` to be a specialization of `integral_constant`, which is inconsistent with the current design of `conjunction` and `disjunction`.

- The requirement in 20.15.2 [meta.rqmts] that "member names of the `BaseCharacteristic` shall not be hidden and shall be unambiguously available" seems impossible to meet in every case, since the arbitrary base class from which a specialization of `conjunction` or `disjunction` derives may contain members called `conjunction` or `disjunction` that will necessarily be hidden.

[2016-08 Chicago]

Ville provided wording for both 2567 and 2568

Previous resolution [SUPERSEDED]:

> In [meta.logical]/3, edit as follows:

> The BaseCharacteristic of a specialization `conjunction<B1, ..., BN>` has a public and unambiguous base that is the first type `Bi` in the list `true_type, B1, ..., BN` for which `Bi::value == false`, or if every `Bi::value != false`, the aforementioned base BaseCharacteristic is the last type in the list. [ Note: This means a specialization of conjunction does not necessarily have a BaseCharacteristic of derive from either true_type or false_type. — end note ]

> In [meta.logical]/6, edit as follows:

> The BaseCharacteristic of a specialization `disjunction<B1, ..., BN>` has a public and unambiguous base that is the first type `Bi` in the list `false_type, B1, ..., BN` for which `Bi::value != false`, or if every `Bi::value == false`, the aforementioned base BaseCharacteristic is the last type in the list. [ Note: This means a specialization of disjunction does not necessarily have a BaseCharacteristic of derive from either true_type or false_type. — end note ]

Previous resolution [SUPERSEDED]:

> In [meta.logical]/3, edit as follows:

> The BaseCharacteristic of a specialization `conjunction<B1, ..., BN>` has a public and unambiguous base that is either
> * the first type `Bi` in the list `true_type, B1, ..., BN` for which `Bi::value == false`, or
> * if there is no such `Bi`, the last type in the list.
> is the first type `Bi` in the list `true_type, B1, ..., BN` for which `Bi::value == false`, or if every `Bi::value != false`, the BaseCharacteristic is the last type in the list.
> [ Note: This means a specialization of `conjunction` does not necessarily have a BaseCharacteristic of derive from either true_type or false_type. — end note ]

> In [meta.logical]/6, edit as follows:

> The BaseCharacteristic of a specialization `disjunction<B1, ..., BN>` has a public and unambiguous base that is either
> * the first type `Bi` in the list `true_type, B1, ..., BN` for which `Bi::value != false`, or
> * if there is no such `Bi`, the last type in the list.
> is the first type `Bi` in the list `true_type, B1, ..., BN` for which `Bi::value != false`, or if every `Bi::value == false`, the BaseCharacteristic is the last type in the list.
> [ Note: This means a specialization of `disjunction` does not necessarily have a BaseCharacteristic of derive from either true_type or false_type. — end note ]

Merged the resolution of 2587 with this issue. This proposed resolution resolves both, and includes fixes from Daniel for negation. Last review of this with LWG turned up a true_type typo in the definition of disjunction, and some editorial changes.

Previous resolution [SUPERSEDED]:

> This wording is relative to N4606.

> 1. In 20.15.9 [meta.logical] p3, edit as follows:

>        template<class... B> struct conjunction : see below { };

>    > -3- The BaseCharacteristic of a specialization `conjunction<B1, ..., BN>` has a public and unambiguous base that is either

>    > - the first type `Bi` in the list `true_type, B1, ..., BN` for which `bool(Bi::value)` is `false`, or
>    > - if there is no such `Bi`, the last type in the list.
>    > is the first type `Bi` in the list `true_type, B1, ..., BN` for which `Bi::value == false`, or if every `Bi::value != false`, the BaseCharacteristic is the last type in the list.

>    > -?- The member names of the base class, other than `conjunction` and `operator=`, shall not be hidden and shall be unambiguously available in `conjunction`. [Note: This means a specialization of `conjunction` does not necessarily have a BaseCharacteristic of inherit from either `true_type` or `false_type`. —end note]

> 2. In 20.15.9 [meta.logical] p6, edit as follows:

>        template<class... B> struct disjunction : see below { };

>    > -6- The BaseCharacteristic of a specialization `disjunction<B1, ..., BN>` has a public and unambiguous base that is either

>    > - the first type `Bi` in the list `true_type, B1, ..., BN` for which `bool(Bi::value)` is `true`, or,
>    > - if there is no such `Bi`, the last type in the list.
>    > is the first type `Bi` in the list `true_type, B1, ..., BN` for which `Bi::value != false`, or if every `Bi::value == false`, the BaseCharacteristic is the last type in the list.

>    > -?- The member names of the base class, other than `disjunction` and `operator=`, shall not be hidden and shall be unambiguously available in `disjunction`. [Note: This means a specialization of `disjunction` does not necessarily have a BaseCharacteristic of inherit from either `true_type` or `false_type`. —end note]

> 3. In 20.15.9 [meta.logical] p8, edit as follows

>        template<class B> struct negation : bool_constant<!bool(B::value)> { };

>    > -8- The class template negation forms the logical negation of its template type argument. The type `negation<B>` is a UnaryTypeTrait with a BaseCharacteristic of `bool_constant<!bool(B::value)>`.

[2016-08-03 Chicago]

Fri AM: Moved to Tentatively Ready

Proposed resolution:

This wording is relative to N4606.

1. In 20.15.9 [meta.logical] p3, edit as follows:

       template<class... B> struct conjunction : see below { };

   > […]

   > -3- The BaseCharacteristic of a specialization `conjunction<B1, ..., BN>` has a public and unambiguous base that is either
   > 1. — the first type `Bi` in the list `true_type, B1, ..., BN` for which `bool(Bi::value)` is `false`, or
   > 2. — if there is no such `Bi`, the last type in the list.
   > is the first type `Bi` in the list `true_type, B1, ..., BN` for which `Bi::value == false`, or if every `Bi::value != false`, the BaseCharacteristic is the last type in the list.[Note: This means a specialization of `conjunction` does not necessarily have a BaseCharacteristic of inherit from either `true_type` or `false_type`. —end note]

   > -?- The member names of the base class, other than `conjunction` and `operator=`, shall not be hidden and shall be unambiguously available in `conjunction`.

2. In 20.15.9 [meta.logical] p6, edit as follows:

       template<class... B> struct disjunction : see below { };

   > […]

   > -6- The BaseCharacteristic of a specialization `disjunction<B1, ..., BN>` has a public and unambiguous base that is either
   > 1. — the first type `Bi` in the list `false_type, B1, ..., BN` for which `bool(Bi::value)` is `true`, or,
   > 2. — if there is no such `Bi`, the last type in the list.
   > is the first type `Bi` in the list `false_type, B1, ..., BN` for which `Bi::value != false`, or if every `Bi::value == false`, the BaseCharacteristic is the last type in the list.[Note: This means a specialization of `disjunction` does not necessarily have a BaseCharacteristic of inherit from either `true_type` or `false_type`. —end note]

   > -?- The member names of the base class, other than `disjunction` and `operator=`, shall not be hidden and shall be unambiguously available in `disjunction`.

3. In 20.15.9 [meta.logical] p8, edit as follows

       template<class B> struct negation : see belowbool_constant<!B::value> { };

   > -8- The class template negation forms the logical negation of its template type argument. The type `negation<B>` is a UnaryTypeTrait with a BaseCharacteristic of `bool_constant<!bool(B::value)>`.