C++ Logo

std-discussion

Advanced search

Template argument equivalence rules don't take user-defined types into account

From: Victor Chernyakin <chernyakin.victor.j_at_[hidden]>
Date: Tue, 3 Mar 2026 14:59:44 +0000
Section 13.8.3.2 [temp.dep.type]/2 says: " A template argument is equivalent to a constant template parameter if it is an identifier that names a variable that is equivalent to the template parameter. A variable is equivalent to a template parameter if - it has the same type as the template parameter (ignoring cv-qualification) and - its initializer consists of a single identifier that names the template parameter or, recursively, such a variable. " This definition doesn't make sense when the template parameter is of a class type for which copy construction isn't equal to a bitcopy. Under the current wording, S<a1> and S<a2> in the following snippet both refer to the current instantiation, but that's clearly bogus: struct A { constexpr A(int k): i(k) {} constexpr A(const A& other): i(other.i + 1) {} int i; }; template <A a1> struct S { static constexpr A a2 = a1; static_assert(!std::same_as<S<a1>, S<a2>>); }; template struct S<1>; I propose adding a 3rd condition to the list above, something like "it is initialized via a trivial copy constructor". But I'm not an expert, there may be a better solution I'm just not seeing. If others agree this is a problem, I'd like to file the core issue for it (it'll be my first one ^_^). In which case, could someone suggest proposed wording? I'm not very fluent in standardese...

Received on 2026-03-03 14:59:51