C++23 Deducing This (explicit object parameter)
Deducing This란
섹션 제목: “Deducing This란”C++23의 explicit object parameter는 멤버 함수의 암묵적 this를 명시적 파라미터로 선언하는 기능입니다. 이를 통해 this의 타입을 템플릿으로 추론할 수 있습니다.
struct Widget { // 기존: 암묵적 this void paint_old() { /* this는 Widget* */ }
// C++23: 명시적 object parameter void paint(this Widget& self) { /* self는 Widget& */ } void paint(this const Widget& self) const { /* const 버전 */ }};문제: const/non-const 중복 제거
섹션 제목: “문제: const/non-const 중복 제거”기존에는 const/non-const 오버로드를 둘 다 작성해야 했습니다.
// C++20 이전: 두 개 필요class Container { std::vector<int> data_;public: int& at(size_t i) { return data_[i]; } const int& at(size_t i) const { return data_[i]; }};
// C++23: 하나로 통합class Container { std::vector<int> data_;public: auto& at(this auto& self, size_t i) { return self.data_[i]; // self가 const면 const int& 반환 }};재귀 람다
섹션 제목: “재귀 람다”기존 람다는 자기 자신을 참조할 수 없었습니다. Deducing this로 해결됩니다.
// C++23: 재귀 람다auto fibonacci = [](this auto self, int n) -> int { if (n <= 1) return n; return self(n - 1) + self(n - 2);};
std::cout << fibonacci(10); // 55CRTP 대체
섹션 제목: “CRTP 대체”기존 CRTP 패턴을 더 간결하게 표현할 수 있습니다.
// 기존 CRTPtemplate<typename Derived>class Base { void interface() { static_cast<Derived*>(this)->implementation(); }};
// C++23 Deducing Thisstruct Base { void interface(this auto& self) { self.implementation(); // 실제 타입의 implementation() 호출 }};
struct Derived : Base { void implementation() { puts("Derived"); }};
Derived d;d.interface(); // "Derived" 출력빌더 패턴 체이닝
섹션 제목: “빌더 패턴 체이닝”파생 클래스에서도 체이닝이 끊기지 않습니다.
struct Builder { int x = 0, y = 0;
auto& setX(this auto& self, int v) { self.x = v; return self; // 실제 타입 반환 } auto& setY(this auto& self, int v) { self.y = v; return self; }};
struct DerivedBuilder : Builder { int z = 0; auto& setZ(this auto& self, int v) { self.z = v; return self; }};
DerivedBuilder b;b.setX(1).setY(2).setZ(3); // 기존 CRTP 없이도 체이닝 유지값/참조/이동 오버로드 통합
섹션 제목: “값/참조/이동 오버로드 통합”struct Obj { std::string data;
// ref qualifier 세 버전을 하나로 decltype(auto) get(this auto&& self) { return std::forward_like<decltype(self)>(self.data); }};
Obj o{"hello"};const Obj co{"world"};
std::string& r1 = o.get(); // lvalue refconst std::string& r2 = co.get(); // const lvalue refstd::string moved = Obj{"!!"}.get(); // rvalue — 이동컴파일러 지원
섹션 제목: “컴파일러 지원”| 컴파일러 | 지원 버전 |
|---|---|
| GCC | 14+ |
| Clang | 18+ |
| MSVC | VS 2022 17.7+ |
this auto& self로this를 명시적으로 받아 const/non-const 중복 제거- 재귀 람다를 간결하게 표현 가능
- CRTP의 복잡한 캐스팅 없이 정적 다형성 구현
- 빌더 패턴에서 파생 클래스도 체이닝이 자연스럽게 유지