Issue 2015: Incorrect pre-conditions for some type traits (original) (raw)


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

2015. Incorrect pre-conditions for some type traits

Section: 21.3.6 [meta.unary] Status: C++14 Submitter: Nikolay Ivchenkov Opened: 2010-11-08 Last modified: 2016-01-28

Priority: Not Prioritized

View all other issues in [meta.unary].

View all issues with C++14 status.

Discussion:

According to N3126 ‑ 3.9/9,

"Scalar types, trivial class types (Clause 9), arrays of such types and _cv_‑qualified versions of these types (3.9.3) are collectively called trivial types."

Thus, an array (possibly of unknown bound) can be trivial type, non‑trivial type, or an array type whose triviality cannot be determined because its element type is incomplete.

According to N3126 ‑ Table 45, preconditions for std::is_trivial are defined as follows:

"T shall be a complete type, (possibly _cv_-qualified) void, or an array of unknown bound"

It seems that "an array of unknown bound" should be changed to "an array of unknown bound of a complete element type". Preconditions for some other templates (e.g., std::is_trivially_copyable,std::is_standard_layout, std::is_pod, and std::is_literal_type) should be changed similarly.

On the other hand, some preconditions look too restrictive. For example, std::is_empty and std::is_polymorphic might accept any incomplete non‑class type.

[2011-02-18: Daniel provides wording proposal]

While reviewing the individual preconditions I could find three different groups of either too weakening or too strengthening constraints:

  1. is_empty/is_polymorphic/is_abstract/has_virtual_destructor:
    These traits can only apply for non‑union class types, otherwise the result must always be false
  2. is_base_of:
    Similar to the previous bullet, but the current wording comes already near to that ideal, it only misses to add the non‑union aspect.
  3. is_trivial/is_trivially_copyable/is_standard_layout/is_pod/is_literal_type:
    These traits always require that std::remove_all_extents<T>::type to be _cv_ void or a complete type.

[Bloomington, 2011]

Move to Ready

Proposed resolution:

  1. Modify the pre-conditions of the following type traits in 21.3.6.4 [meta.unary.prop], Table 48 — Type property predicates:

    Table 48 — Type property predicates

    Template Condition Preconditions
    ...
    template struct is_trivial; T is a trivial type (3.9) remove_all_extents<T>::typeshall be a complete type, or (possiblycv-qualified) void, or an array ofunknown bound.
    template struct is_trivially_copyable; T is a trivially copyabletype (3.9) remove_all_extents<T>::typeshall be a complete type, or (possiblycv-qualified) void, or an array ofunknown bound.
    template struct is_standard_layout; T is a standard-layouttype (3.9) remove_all_extents<T>::typeshall be a complete type, or (possiblycv-qualified) void, or an array ofunknown bound.
    template struct is_pod; T is a POD type (3.9) remove_all_extents<T>::typeshall be a complete type, or (possiblycv-qualified) void, or an array ofunknown bound.
    template struct is_literal_type; T is a literal type (3.9) remove_all_extents<T>::typeshall be a complete type, or (possiblycv-qualified) void, or an array ofunknown bound.
    template struct is_empty; T is a class type, but not aunion type, with nonon-static data membersother than bit-fields oflength 0, no virtualmember functions, novirtual base classes, andno base class B for which is_empty::value isfalse. T shall be a complete type,(possibly cv-qualified) void, oran array of unknown boundIf Tis a non‑union class type, Tshall be a complete type.
    template struct is_polymorphic; T is a polymorphicclass (10.3) T shall be a complete type,type, (possibly cv-qualified) void, oran array of unknown boundIf Tis a non‑union class type, Tshall be a complete type.
    template struct is_abstract; T is an abstractclass (10.4) T shall be a complete type,type, (possibly cv-qualified) void, oran array of unknown boundIf Tis a non‑union class type, Tshall be a complete type.
    ...
    template struct has_virtual_destructor; T has a virtualdestructor (12.4) T shall be a complete type,(possibly cv-qualified) void, oran array of unknown boundIf Tis a non‑union class type, Tshall be a complete type.
  2. Modify the pre-conditions of the following type traits in 21.3.8 [meta.rel], Table 50 — Type relationship predicates:

    Table 50 — Type relationship predicates

    Template Condition Comments
    ...
    template <class Base, classDerived>struct is_base_of; Base is a base class of Derived (10) withoutregard to cv-qualifiersor Base and Derivedare not unions andname the same classtype without regard tocv-qualifiers If Base and Derived are non‑union class typesand are different types(ignoring possible cv-qualifiers)then Derived shall be a completetype. [ Note: Base classes thatare private, protected, orambigious are, nonetheless, baseclasses. — end note ]
    ...