I try to have a member function require a static constexpr boolean member to be true. This would be very helpful to DRY a quite complex requirement. And I do not quire get the reason why the compiler won't let me.
Minimal example with slightly less complex requirement:
template <typename T>
struct Foo
{
static constexpr bool isInt = std::integral<T>;
void bar() requires (isInt);
void goo() requires std::integral<T>;
};
template <typename T>
void Foo<T>::bar() requires (Foo<T>::isInt) // error: out-of-line definition of 'bar' does not match any declaration in 'Foo<T>' x86-64 clang 14.0.0 #1
{
// ...
}
template <typename T>
void Foo<T>::goo() requires std::integral<T> // ok
{
// ...
}
Is this because isInt
is declared inside the same class? Or do I have some kind of syntax error?
CodePudding user response:
There is a question of whether or not your requires
clauses in the in-class declaration and out-of-class definition are equivalent (or functionally equivalent).
But regardless of the answer to that question, the easiest solution is to simply use the exact same token sequence, which will be certain to be equivalent:
template <typename T>
void Foo<T>::bar() requires (isInt)
{
// ...
}
However, current Clang releases don't accept any variations I try to name the static member, especially not those using the same token sequence in both declaration and definition. At least that last part is definitively a bug.
But on current Clang trunk all variations are accepted, indicating that this is a recently fixed bug.
CodePudding user response:
Seems like an MSVC bug. Here's a workaround:
#include <concepts>
template <class T>
concept isInt = std::integral<T>;
template <typename T>
struct Foo
{
void bar() requires (isInt<T>);
};
template <typename T>
void Foo<T>::bar() requires (isInt<T>)
{
}