8

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?

1

1 Answer 1

5

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.

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.