Namespaces
Variants
Actions

Talk:cpp/language/crtp

From cppreference.com

The C++23 code listing given in the example here isn't CRTP, the two code listings given aren't equivalent at all. The equivalent non-C++23 code would be given by:

#include <cstdio>
 
#ifndef __cpp_explicit_this_parameter // Traditional syntax
 
struct Base { static void name(auto&& self) { self.impl(); } };
struct D1 : public Base { void impl() { std::puts("D1::impl()"); } };
struct D2 : public Base { void impl() { std::puts("D2::impl()"); } };
 
void test()
{
    D1 d1; D1::name(d1);
    D2 d2; D2::name(d2);
}
 
#else // C++23 alternative syntax; https://godbolt.org/z/s1o6qTMnP
 
struct Base { void name(this auto&& self) { self.impl(); } };
struct D1 : public Base { void impl() { std::puts("D1::impl()"); } };
struct D2 : public Base { void impl() { std::puts("D2::impl()"); } };
 
void test()
{
    D1 d1; d1.name();
    D2 d2; d2.name();
}
 
#endif
 
int main()
{
    test();
}

Possible output:

D1::impl()
D2::impl()

The code here calls derived functions from the base class, but it's not CRTP, although it is somewhat in the same spirit as CRTP, hence why I haven't removed the code from the page. I do want to stress that the explicit object parameter doesn't allow us to do anything we couldn't do before though (such as call functions defined in a derived class from a base class without making the base class a template), it merely provides a different syntax to call the base class function. --Ybab321 (talk) 12:56, 26 January 2023 (PST)