Consider this program which uses the curiously recurring template pattern:
template <typename T>
concept Frobulates = requires (T t) { t.frobulate(); };
template <typename Derived>
struct S {
int sidefumble() requires Frobulates<Derived> {
Derived::frobulate();
}
};
struct K: public S<K> {
void frobulate() {}
};
int main() {
K k;
k.sidefumble();
}
When compiled, it generates this error using clang++
version 13.0.0:
$ clang13 -std=c++20 ./recurring-concept.cpp -o recurring-concept && ./recurring-concept
./recurring-concept.cpp:17:7: error: invalid reference to function 'sidefumble': constraints not satisfied
k.sidefumble();
^
./recurring-concept.cpp:6:31: note: because 'K' does not satisfy 'Frobulates'
int sidefumble() requires Frobulates<Derived> {
^
./recurring-concept.cpp:2:41: note: because 't.frobulate()' would be invalid: no member named 'frobulate' in 'K'
concept Frobulates = requires (T t) { t.frobulate(); };
^
1 error generated.
Specifically, the compiler reports that the type K
does not have a member frobulate()
, but this is plainly false.
I would expect that sidefumble()
is compileable, just as it would be if the requires
statement were not present.
- Is this expected/designed behavior? (It seems conceivable to me that possible use of the CRTP, being somewhat of an unusual corner case, might not have been accounted for in the design and/or implementation of this very young feature)
- At the very least, the error message is badly misleading. Where is the appropriate place to start a discussion among compiler/standards authors about the handling of this case?
- Is there a workaround?