Date: Mon, 13 Jan 2025 15:41:02 -0500
Unfortunately, that doesn't work.
template <typename T>
struct A {
static int x;
};
int f() {
return A<int>::x + A<long>::x;
}
template <>
int A<int>::x = 4;
<source>:14:13: error: explicit specialization of 'x' after
instantiation
14 | int A<int>::x = 4;
| ^
<source>:8:20: note: implicit instantiation first required here
8 | return A<int>::x + A<long>::x;
| ^
1 error generated.
Compiler returned: 1
On Mon, 2025-01-13 at 21:13 +0200, Avi Kivity wrote:
> There is a simple workaround: a static variable in a class template:
>
> template <typename T>
> struct A {
> static int var;
> };
> // A<int>::var can be referenced without the initializer being
> defined
> at this point
>
> template <> int A<int>::var = 7;
>
> On Mon, 2025-01-13 at 20:07 +0200, Avi Kivity wrote:
> > It's possible to declare-but-not-define a full specialization of a
> > function or variable template:
> >
> > template <typename T> void function_template();
> > extern template void function_template<int>(); // Some other TU
> > must
> > define, but any TU can reference
> >
> > template <typename T> class class_template;
> > template <> class class_template<int>; // Incomplete type, but can
> > still be used
> >
> > However, it's not possible [1] to declare-but-not-define a variable
> > template full specialization.
> >
> > template <typename T> extern int variable_template;
> > template <> extern int variable_template<int>; // rejected
> >
> > Such a declaration-but-not-definition would allow the initializer
> > for
> > the variable template to be hidden from its users, for the purpose
> > of
> > reducing compile-time dependencies.
> >
> > I wasn't able to fully determine if the defect is in the Standard,
> > in
> > existing implementations, or in the user interpreting the Standard
> > and
> > existing implementations.
>
template <typename T>
struct A {
static int x;
};
int f() {
return A<int>::x + A<long>::x;
}
template <>
int A<int>::x = 4;
<source>:14:13: error: explicit specialization of 'x' after
instantiation
14 | int A<int>::x = 4;
| ^
<source>:8:20: note: implicit instantiation first required here
8 | return A<int>::x + A<long>::x;
| ^
1 error generated.
Compiler returned: 1
On Mon, 2025-01-13 at 21:13 +0200, Avi Kivity wrote:
> There is a simple workaround: a static variable in a class template:
>
> template <typename T>
> struct A {
> static int var;
> };
> // A<int>::var can be referenced without the initializer being
> defined
> at this point
>
> template <> int A<int>::var = 7;
>
> On Mon, 2025-01-13 at 20:07 +0200, Avi Kivity wrote:
> > It's possible to declare-but-not-define a full specialization of a
> > function or variable template:
> >
> > template <typename T> void function_template();
> > extern template void function_template<int>(); // Some other TU
> > must
> > define, but any TU can reference
> >
> > template <typename T> class class_template;
> > template <> class class_template<int>; // Incomplete type, but can
> > still be used
> >
> > However, it's not possible [1] to declare-but-not-define a variable
> > template full specialization.
> >
> > template <typename T> extern int variable_template;
> > template <> extern int variable_template<int>; // rejected
> >
> > Such a declaration-but-not-definition would allow the initializer
> > for
> > the variable template to be hidden from its users, for the purpose
> > of
> > reducing compile-time dependencies.
> >
> > I wasn't able to fully determine if the defect is in the Standard,
> > in
> > existing implementations, or in the user interpreting the Standard
> > and
> > existing implementations.
>
Received on 2025-01-13 20:41:10