CWG Issue 2604 (original) (raw)

This is an unofficial snapshot of the ISO/IEC JTC1 SC22 WG21 Core Issues List revision 118f. See http://www.open-std.org/jtc1/sc22/wg21/ for the official list.

2025-11-07


2604. Attributes for an explicit specialization

Section: 13.9.4 [temp.expl.spec]Status: C++23Submitter: Aaron BallmanDate: 2022-06-23

[Accepted as a DR at the November, 2022 meeting.]

It is unclear whether an explicit template specialization "inherits" the attributes written on the primary template, or whether the specialization has to repeat the attributes. For example:

template [[noreturn]] void func(Ty);

template <> void func(int) { // Warning about returning from a noreturn function or not? }

A similar question arises for attributes written on the parameters of the primary function template. For example:

template void func([[maybe_unused]] int i);

template <> void func(int i) { // i is not used, should it be warned on or not? }

There is implementation divergence for the example.

Suggested resolution [SUPERSEDED]:

Change in 13.9.4 [temp.expl.spec] paragraph 13 as follows:

Any attributes applying to any part of the declaration of an explicit specialization of a function or variable template, as well as Whether whether such an explicit specialization of a function or variable template is inline, constexpr, or an immediate function, is determined by the explicit specialization and is independent of those properties of the template.[ Note: Attributes that would affect the association of the declaration of an explicit specialization with the declaration of the primary template need to match. -- end note ]

Proposed resolution (approved by CWG 2022-11-09):

Change 13.9.4 [temp.expl.spec] paragraph 13 as follows:

Whether an explicit specialization of a function or variable template is inline, constexpr, or an immediate function is determined by the explicit specialization and is independent of those properties of the template. Similarly, attributes appearing in the declaration of a template have no effect on an explicit specialization of that template. [Example 7:

template void f(T) { /* ... / } template inline T g(T) { / ... */ }

template<> inline void f<>(int) { /* ... / } // OK, inline template<> int g<>(int) { / ... */ } // OK, not inline

template [[noreturn]] void h([[maybe_unused]] int i); template<> void h(int i) { // Implementations are expected not to warn that the function returns but can // warn about the unused parameter. }

—_end example_]