[temp.constr.order]

# 13 Templates [[temp]](./#temp)

## 13.5 Template constraints [[temp.constr]](temp.constr#order)

### 13.5.5 Partial ordering by constraints [temp.constr.order]

[1](#1)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/templates.tex#L2299)

A constraint P [*subsumes*](#def:constraint,subsumption "13.5.5 Partial ordering by constraints [temp.constr.order]") a constraint Q if and only if,
for every disjunctive clause Pi in the disjunctive normal form[110](#footnote-110 "A constraint is in disjunctive normal form when it is a disjunction of clauses where each clause is a conjunction of fold expanded or atomic constraints. For atomic constraints A, B, and C, the disjunctive normal form of the constraint A  â§ (B  â¨ C) is (A  â§ B)  â¨ (A  â§ C). Its disjunctive clauses are (A  â§ B) and (A  â§ C).") of P, Pi subsumes every conjunctive clause Qj in the conjunctive normal form[111](#footnote-111 "A constraint is in conjunctive normal form when it is a conjunction of clauses where each clause is a disjunction of fold expanded or atomic constraints. For atomic constraints A, B, and C, the constraint A  â§ (B  â¨ C) is in conjunctive normal form. Its conjunctive clauses are A and (B  â¨ C).") of Q, where

- [(1.1)](#1.1)

a disjunctive clause Pi subsumes a conjunctive clause Qj if and only
if there exists an atomic constraint Pia in Pi for which there exists
an atomic constraint Qjb in Qj such that Pia subsumes Qjb,

- [(1.2)](#1.2)

an atomic constraint A subsumes another atomic constraintB if and only if A and B are identical using the
rules described in [[temp.constr.atomic]](temp.constr.atomic "13.5.2.3 Atomic constraints"), and

- [(1.3)](#1.3)

a fold expanded constraint A subsumes
another fold expanded constraint B if they are compatible for subsumption,
have the same [*fold-operator*](expr.prim.fold#nt:fold-operator "7.5.7 Fold expressions [expr.prim.fold]"), and
the constraint of A subsumes that of B[.](#1.sentence-1)

[*Example [1](#example-1)*:

Let A and B be [atomic constraints](temp.constr.atomic#def:constraint,atomic "13.5.2.3 Atomic constraints [temp.constr.atomic]")[.](#1.sentence-2)

The constraint A â§ B subsumes A, but A does not subsume A â§ B[.](#1.sentence-3)

The constraint A subsumes A â¨ B, but A â¨ B does not subsume A[.](#1.sentence-4)

Also note that every constraint subsumes itself[.](#1.sentence-5)

â *end example*]

[2](#2)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/templates.tex#L2354)

[*Note [1](#note-1)*:

The subsumption relation defines a partial ordering on constraints[.](#2.sentence-1)

This partial ordering is used to determine

- [(2.1)](#2.1)

the best viable candidate of non-template functions ([[over.match.best]](over.match.best "12.2.4 Best viable function")),

- [(2.2)](#2.2)

the address of a non-template function ([[over.over]](over.over "12.3 Address of an overload set")),

- [(2.3)](#2.3)

the matching of template template arguments ([[temp.arg.template]](temp.arg.template "13.4.4 Template template arguments")),

- [(2.4)](#2.4)

the partial ordering of class template specializations ([[temp.spec.partial.order]](temp.spec.partial.order "13.7.6.3 Partial ordering of partial specializations")), and

- [(2.5)](#2.5)

the partial ordering of function templates ([[temp.func.order]](temp.func.order "13.7.7.3 Partial ordering of function templates"))[.](#2.sentence-2)

â *end note*]

[3](#3)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/templates.tex#L2367)

The associated constraints C of a declaration Dare [*eligible for subsumption*](#def:eligible,for_subsumption "13.5.5 Partial ordering by constraints [temp.constr.order]") unless C contains a concept-dependent constraint[.](#3.sentence-1)

[4](#4)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/templates.tex#L2378)

A declaration D1 is[*at least as constrained*](#def:at_least_as_constrained "13.5.5 Partial ordering by constraints [temp.constr.order]") as
a declaration D2 if

- [(4.1)](#4.1)

D1 and D2 are both constrained declarations andD1's associated constraints
are eligible for subsumption and subsume those of D2; or

- [(4.2)](#4.2)

D2 has no associated constraints[.](#4.sentence-1)

[5](#5)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/templates.tex#L2390)

A declaration D1 is [*more constrained*](#def:more_constrained "13.5.5 Partial ordering by constraints [temp.constr.order]") than another declaration D2 when D1 is at least as
constrained as D2, and D2 is not at least as
constrained as D1[.](#5.sentence-1)

[*Example [2](#example-2)*: template<typename T> concept C1 = requires(T t) { --t; };template<typename T> concept C2 = C1<T> && requires(T t) { *t; };

template<C1 T> void f(T); // #1template<C2 T> void f(T); // #2template<typename T> void g(T); // #3template<C1 T> void g(T); // #4 f(0); // selects #1 f((int*)0); // selects #2 g(true); // selects #3 because C1<bool> is not satisfied g(0); // selects #4 â *end example*]

[*Example [3](#example-3)*: template<template<typename T> concept CT, typename T>struct S {};template<typename T>concept A = true;

template<template<typename T> concept X, typename T>int f(S<X, T>) requires A<T> { return 42; } // #1template<template<typename T> concept X, typename T>int f(S<X, T>) requires X<T> { return 43; } // #2 f(S<A, int>{}); // ok, select #1 because #2 is not eligible for subsumption â *end example*]

[6](#6)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/templates.tex#L2427)

A non-template function F1 is [*more partial-ordering-constrained*](#def:more_partial-ordering-constrained "13.5.5 Partial ordering by constraints [temp.constr.order]") than a non-template function F2 if

- [(6.1)](#6.1)

they have the same non-object-parameter-type-lists ([[dcl.fct]](dcl.fct "9.3.4.6 Functions")), and

- [(6.2)](#6.2)

if they are member functions, both are direct members of the same class, and

- [(6.3)](#6.3)

if both are non-static member functions,
they have the same types for their object parameters, and

- [(6.4)](#6.4)

the declaration of F1 is more constrained than
the declaration of F2[.](#6.sentence-1)

[110)](#footnote-110)[110)](#footnoteref-110)

A constraint is in disjunctive normal form when it is a disjunction of
clauses where each clause is a conjunction of fold expanded or atomic constraints[.](#footnote-110.sentence-1)

For atomic constraints A, B, and C, the disjunctive normal form
of the constraintA â§ (B â¨ C) is(A â§ B) â¨ (A â§ C)[.](#footnote-110.sentence-2)

Its disjunctive clauses are (A â§ B) and (A â§ C)[.](#footnote-110.sentence-3)

[111)](#footnote-111)[111)](#footnoteref-111)

A constraint is in conjunctive normal form when it is a conjunction
of clauses where each clause is a disjunction of fold expanded or atomic constraints[.](#footnote-111.sentence-1)

For atomic constraints A, B, and C, the constraintA â§ (B â¨ C) is in conjunctive normal form[.](#footnote-111.sentence-2)

Its conjunctive clauses are A and (B â¨ C)[.](#footnote-111.sentence-3)
