The C++ program below compiles with GCC trunk:
template <typename T>
struct Foo
{
constexpr void test();
};
void not_constexpr() {}
template <>
constexpr void Foo<int>::test() { }
template <>
void Foo<float>::test() { not_constexpr(); }
int main() {}
But fails with Clang and MSVC. The error message is:
<source>:13:28: error: non-constexpr declaration of 'test' follows constexpr declaration
13 | void Foo<float>::test() { not_constexpr(); }
| ^
<source>:4:18: note: previous declaration is here
4 | constexpr void test();
This can be seen on Compiler Explorer here. Which compiler is correct?
GCC is correct: inline, constexpr, constinit, consteval, attributes, and contracts are independent for explicit specializations ([temp.expl.spec]/12). The situation is complicated by the special feature of specializing a member of a class template rather than a function template directly (which Clang supports), but that doesn’t make the previous declaration any more controlling.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With