1. Vấn đề nó giải quyết
Khi kiểu đối tượng đã được suy luận, member có thể ràng buộc kiểu đó như mọi tham số template khác. Kết quả là một member generic có quy tắc tham gia dễ đọc.
2. Kiến thức cần có
Ngày 4: concept và template có ràng buộc.
Ngày 11–12: object parameter tường minh và được suy luận.
3. Ý tưởng cốt lõi
Explicit object parameter mở một cánh cổng; concept là người gác kiểm tra đối tượng đi vào có các phép toán mà thân hàm cần hay không. Hãy xác định giá trị đang được biến đổi rồi kiểm tra kiểu, lifetime hoặc quyền sở hữu kết quả. Bật C++23 chưa chắc thư viện đã triển khai đủ, vì vậy cần kiểm tra feature-test macro liên quan.
4. Cú pháp tối thiểu
template<class Self>
requires HasValue<Self>
int read(this Self const& self);5. Cách nó hoạt động
Ví dụ tạo biểu thức hoặc đối tượng nhỏ nhất cho Deducing
thisvới templates và concepts.Chương trình gọi member explicit-object có ràng buộc trên kiểu thỏa
HasValue.Cuối cùng, nó in hoặc kiểm tra giá trị bên trong, còn hình dạng đối tượng sai bị loại trước khi instantiate thân hàm để dễ đối chiếu.
6. Lỗi thường gặp
Ràng buộc sai dạng
Selfcó thể vô tình loại lời gọiconsthoặc có tham chiếu; concept cú pháp vẫn có thể thiếu yêu cầu ngữ nghĩa.Không kiểm tra feature-test macro có thể chọn nhánh mã thư viện hiện tại chưa hỗ trợ.
7. Khi nào nên dùng
Nên dùng khi mixin generic có member chỉ nên tồn tại cho hình dạng đối tượng dẫn xuất tương thích.
Tránh dùng khi thêm concept chỉ lặp lại lỗi vốn đã rõ trong member không generic.
8. Ví dụ đơn giản
Mixin tuần tự hóa chỉ bật save() khi đối tượng cuối cung cấp đủ trường cần thiết. Chương trình dùng dữ liệu cố định để output dễ kiểm tra.
Mã mẫu hoàn chỉnh
Tệp mã nguồn
cpp23/13_deducing_this_templates_concepts/main.cpp
#include <concepts>
#include <iostream>
#if defined(__cpp_explicit_this_parameter)
template <class T>
concept HasValue = requires(const T& object) {
{ object.value } -> std::convertible_to<int>;
};
struct Box {
int value{42};
template <class Self>
int read(this const Self& self) requires HasValue<Self> {
return self.value;
}
};
#endif
int main() {
#if defined(__cpp_explicit_this_parameter)
const Box box;
std::cout << box.read() << '\n';
#else
std::cout << "constrained deducing this unavailable\n";
#endif
}
9. Điều cần nhớ
Tách quy tắc chuẩn khỏi mức hỗ trợ thực tế.
Làm rõ lifetime, ownership và kiểu suy luận.
Ưu tiên cú pháp ngắn, đúng ý định.
Guard tính năng chưa được hỗ trợ đồng đều.
10. Câu hỏi tự kiểm tra
Dễ — Cú pháp ngắn nhất ở Phần 4 là gì và nhiệm vụ chính của nó là gì?
Trung bình — Đọc chương trình mẫu: giá trị, kiểu hoặc nhánh nào được quan sát, và vì sao?
Khó —
HasValue<Self>nên kiểm traSelf,remove_reference_t<Self>hay biểu thức trênself, và lựa chọn đó thay đổi lời gọi const-reference thế nào?