P4004R0 - Reconsider CWG 1395 "Partial ordering of variadic templates reconsidered" WG21
Posted by u/variadic_dispatch_42 · 7 hr. ago

Author: Christof Meerwald (NVIDIA)
Document: P4004R0
Date: 2026-02-22
Target: EWG
Link: wg21.link/p4004r0

Christof Meerwald is asking EWG to revisit the resolution of CWG 1395, a core defect report from 2016 that changed how variadic and non-variadic function templates get partially ordered during overload resolution. The short version: the accepted resolution fundamentally changed how function parameter packs work during partial ordering, but a decade later only EDG actually implements it that way. GCC, Clang, and MSVC all do something different - and users expect the GCC/Clang/MSVC behavior.

The paper proposes two options. Option 1 reverts most of the CWG 1395 changes but keeps the trailing-pack tiebreaker in [temp.deduct.partial]/11, which would standardize what the three major compilers already do. Option 2 goes further and resolves additional ambiguity from CWG 1825. Full proposed wording is included for Option 1.

▲ 31 points (89% upvoted) · 8 comments
sorted by: best
u/not_a_language_lawyer 41 points 6 hr. ago

A paper to reconsider a resolution that reconsidered partial ordering. We have achieved template meta-standardization.

u/constexpr_all_the_things 9 points 3 hr. ago

partial_ordering(partial_ordering(variadic_templates)). It compiles but instantiation has been pending since 2016.

u/daily_segfault 28 points 5 hr. ago

I have been writing C++ professionally for over a decade and I'm not sure I've ever consciously thought about partial ordering of variadic templates. This paper is for people operating three standard-ese layers above me.

u/actually_reads_the_papers 16 points 4 hr. ago

The key sentence:

10 years later only EDG implements that approach and gets bugs reports for real-world code where users expect a different partial ordering result.

So GCC, Clang, and MSVC all agree on one behavior, the standard specifies something else, only EDG follows the standard, and EDG's users file bugs because they expect the GCC/Clang behavior. This is about as clear-cut a case for "standardize existing practice" as you're going to find.

Option 1 is conservative - revert the pack-expansion deduction changes but keep the trailing-pack tiebreaker in [temp.deduct.partial]/11. Straightforward fix.

u/actually_reads_the_papers 5 points 3 hr. ago

Also worth noting - Option 2 (making the CWG 1825 example pick an overload instead of staying ambiguous) is left open without full wording. That feels like the more interesting design question. GCC and MSVC already pick #2 there, Clang says ambiguous. If we're standardizing existing practice, might as well go all the way.

u/overload_resolution_enjoyer 11 points 5 hr. ago
Having a feature specified in a way almost no one implements is not really useful, particularly if there are additional issues with that specification that need to be fixed.

Hard to argue with that. When three implementations agree and the spec disagrees, the spec is the bug. The observation that the current wording doesn't even have normative backing for its own examples in [temp.deduct.partial]/8 is the cherry on top.

u/mass_transit_dev -3 points 1 hr. ago

An entire paper about which of two function templates wins overload resolution, where even the committee's own defect resolution doesn't match what compilers actually do. This is the kind of thing that makes me sympathize with the "C++ is too complicated" crowd.

u/former_boost_user_ama 4 points 47 minutes ago

The partial ordering rules have an edge case that went unnoticed in practice for a decade. If anything that's evidence the system works fine for real code. This is cleanup, not a crisis.