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.

### 2467. `is_always_equal` has slightly inconsistent default

Section: 16.4.4.6 [allocator.requirements], 20.10.8.2 [allocator.traits.types] Status: C++17 Submitter: Howard Hinnant Opened: 2015-01-18 Last modified: 2017-07-30

Priority: 0

View other active issues in [allocator.requirements].

View all other issues in [allocator.requirements].

View all issues with C++17 status.

Discussion:

Table 28 — "Allocator requirements" says that `X::is_always_equal` has a default value of `is_empty<X>`, and this is consistent with the return type description:

> Identical to or derived from `true_type` or `false_type`

`is_empty<X>` is guaranteed to be derived from either `true_type` or `false_type`. So far so good.

20.10.8.2 [allocator.traits.types]/p10 says:

>     typedef see below is_always_equal;

> > Type: `Alloc::is_always_equal` if the qualified-id `Alloc::is_always_equal` is valid and denotes a type (14.8.2); otherwise `is_empty<Alloc>::type`.

This is subtly different than what Table 28 says is the default: `is_empty<Alloc>::type` is not `is_empty<Alloc>`, but is rather one of `true_type` or `false_type`.

There are two ways to fix this:

1. Change Table 28 to say: `is_empty<X>::type`.

   or

2. Change 20.10.8.2 [allocator.traits.types]/p10:

   > Type: `Alloc::is_always_equal` if the qualified-id `Alloc::is_always_equal` is valid and denotes a type (14.8.2); otherwise `is_empty<Alloc>::type`.

Both options are correct, and I see no reason to prefer one fix over the other. But Table 28 and 20.10.8.2 [allocator.traits.types]/p10 should be consistent with one another.

[2015-02 Cologne]

DK: We should accept the first bullet. GR: Why does `is_empty` even have a type member? AM: All type traits have a type member. I agree with DK's preference for the first type.

Proposed resolution:

This wording is relative to N4296.

1. Change 16.4.4.6 [allocator.requirements], Table 28 — "Allocator requirements" as presented:

   > Table 28 — Allocator requirements
   > Expression | Return type | Assertion/note pre-/post-condition | Default
   > --- | --- | --- | ---
   > `…`
   > `X::is_always_equal` | Identical to or derived from `true_type` or `false_type` | […] | `is_empty<X>::type`
   > `…`