---
title: "Proposed\nresolution for US70-126: allow incomplete types in type_order"
document: p4140r0
date: 2026-03-23
audience: LEWG Library Evolution,LWG Library
reply-to:
  - "Gašper Ažman"
paper-type: proposal
---

# Proposed
resolution for US70-126: allow incomplete types in type_order

Repy-to: Gašper Ažman [gasper.azman@gmail.com](mailto:gasper.azman@gmail.com) Date: 2026-03-23 Paper number: P4140R0

## Context

The `type_ordering` metafunction (17.11.7 [compare.type](https://eel.is/c++draft/compare.type)) is specified in terms of a literal struct definition

```
template<class T, class U> struct type_order {
  static constexpr strong_ordering value = TYPE-ORDER(T, U);

  using value_type = strong_ordering;

  constexpr operator value_type() const noexcept { return value; }
  constexpr value_type operator()() const noexcept { return value; }
};
```

It used to be defined in terms of [`Cpp17BinaryTypeTrait`](https://eel.is/c++draft/meta.rqmts#2), but changed this in [P3778R0](https://isocpp.org/files/papers/P3778R0.html) due to `std::strong_ordering` not being a structural type.

During that change, the explicit allowance for `type_order<X, Y>` being defined for incomplete `X` or `Y` got inadvertently dropped, so this paper re-introduces that allowance.

This is not a change in design - this is a fixup to make the wording consistent with the design as passed in [P2830R10](https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2025/p2830r10.html).

## Proposed Wording

> 1. If an explicit specialization or partial specialization of type_order is declared, the program is ill-formed.
> 2. The templates `type_order` and `type_order_v` may be instantiated with incomplete types as arguments.
> 3. Recommended practice: The order should be lexicographical on parameter-type-lists and template argument lists.
