Date: Wed, 4 Mar 2026 05:55:49 +0000
There's a Defect Report P2308R1 (https://wg21.link/p2308r1, see also https://eel.is/c++draft/temp.arg.nontype#4.3), which clarified that if one provides a template argument value whose copy operation doesn't meet the template argument equivalence requirements, the program is ill-formed.
Thanks,
F.v.S.
________________________________
From: Std-Discussion <std-discussion-bounces_at_[hidden]> on behalf of Victor Chernyakin via Std-Discussion <std-discussion_at_[hidden]>
Sent: Tuesday, March 3, 2026 22:59
To: std-discussion_at_[hidden] <std-discussion_at_[hidden]>
Cc: Victor Chernyakin <chernyakin.victor.j_at_[hidden]>
Subject: [std-discussion] Template argument equivalence rules don't take user-defined types into account
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...
Thanks,
F.v.S.
________________________________
From: Std-Discussion <std-discussion-bounces_at_[hidden]> on behalf of Victor Chernyakin via Std-Discussion <std-discussion_at_[hidden]>
Sent: Tuesday, March 3, 2026 22:59
To: std-discussion_at_[hidden] <std-discussion_at_[hidden]>
Cc: Victor Chernyakin <chernyakin.victor.j_at_[hidden]>
Subject: [std-discussion] Template argument equivalence rules don't take user-defined types into account
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...
-- Std-Discussion mailing list Std-Discussion_at_[hidden] https://lists.isocpp.org/mailman/listinfo.cgi/std-discussion
Received on 2026-03-04 05:55:53
