https://gcc.gnu.org/bugzilla/show_bug.cgi?id=84795
Bug ID: 84795
Summary: Explicit specialization of constexpr static data
member incorrectly rejected in C++17
Product: gcc
Version: 8.0.1
Status: UNCONFIRMED
Severity: normal
Priority: P3
Component: c++
Assignee: unassigned at gcc dot gnu.org
Reporter: inadgob at yahoo dot com
Target Milestone: ---
The following code is incorrectly rejected in C++17 mode:
template<class T> struct A { static constexpr int v = 7; };
template<> constexpr int A<int>::v = 3;
static_assert(A<int>::v == 3);
int main() { }
Compiled with -std=c++17 -pedantic -Wall -Wextra. Diagnostic:
prog.cc:3:34: error: duplicate initialization of 'A<int>::v'
template<> constexpr int A<int>::v = 3;
^
Rejecting this would be correct in C++14 mode, where the initializer is part of
the declaration that is instantiated as part of the implicit instantiation of
A<int>. However, in C++17 v is implicitly inline, so its declaration is a
definition, which shouldn't be instantiated as part of the implicit
instantiation. I believe this is covered by [temp.expl.spec]/15:
> A member or a member template of a class template may be explicitly
> specialized for a given implicit instantiation of the class template,
> even if the member or member template is defined in the class template
> definition.