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

Section: 23.15.8 [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:

[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 baseBaseCharacteristic 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 baseBaseCharacteristic 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 23.15.8 [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 23.15.8 [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 23.15.8 [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 23.15.8 [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 23.15.8 [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 23.15.8 [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)>.