I'm trying to use C++23's explicit object parameters (as introduced in P0847R7, "Deducing this") to replace the Curiously Recurring Template Pattern (CRTP) for a simple inheritance hierarchy, but I'm encountering a compiler error with Clang 20.1.2. The error suggests that the compiler cannot find a method (draw_impl) in the base class, even though it should be available in the derived class. This behavior contradicts examples in both the C++ proposal and a CppCon 2023 talk on non-virtual polymorphism, where explicit object parameters are advertised as a cleaner alternative to CRTP.
Here’s a minimal reproducible example:
#include <print>
struct shape {
void draw(this auto&& self) {
return self.draw_impl(); // Error: no member named 'draw_impl' in 'shape'
}
};
struct triangle : public shape {
void draw_impl() {
std::println("{}", "triangle");
}
};
void draw_shapes(shape& type) {
type.draw();
}
auto main() -> int {
auto tri = triangle{};
draw_shapes(tri);
return 0;
}
When I compile this with Clang 20.1.2 and -std=c++2c (C++26 mode) using CMake, I get the following error:
main.cpp:5:16: error: no member named 'draw_impl' in 'shape'
5 | return self.draw_impl();
| ~~~~ ^
main.cpp:16:8: note: in instantiation of function template specialization 'shape::draw<shape &>' requested here
16 | type.draw();
| ^
1 error generated.
Questions:
- Is this a limitation or bug in Clang 20.1.2’s implementation of C++26 explicit object parameters?
- Did the design intent of explicit object parameters change between P0847R7 and C++26, making it unsuitable for direct CRTP replacement?
- Does this work for others using different compilers (e.g., GCC, MSVC)? If so, what am I missing?
Environment:
- Compiler: Clang 20.1.2
- Standard: C++26 (
-std=c++2c) - Build System: CMake
I’d appreciate any insights or workarounds. If this is expected behavior, could someone explain why and how to adjust my design to achieve the same goal as CRTP (i.e., allowing a base class to delegate to derived class methods without templates on the base)?