1. Vấn đề nó giải quyết
Khi nhiều constrained overload đều hợp lệ, subsumption giúp compiler chọn overload có constraint cụ thể hơn. Nó làm một giả định quan trọng trở nên rõ và có thể kiểm tra.
2. Kiến thức cần có
Custom concept, standard concept và overload.
Bạn cần biết biên dịch chương trình ngắn và đọc output.
3. Ý tưởng cốt lõi
Hãy nghĩ đến các cánh cổng lồng nhau: mọi signed integral đều là integral nên cổng signed hẹp hơn. Giá trị qua được cả hai sẽ vào overload hẹp. Hãy đọc subsumption như lời hứa chính xác; runtime precondition vẫn do lập trình viên chịu trách nhiệm.
4. Cú pháp tối thiểu
template<class T> concept SignedInt = std::integral<T> && std::signed_integral<T>;5. Cách nó hoạt động
Chương trình đưa vào dạng nhỏ nhất cần thiết của
subsumption.Nó áp dụng tính năng lên dữ liệu cố định và giữ owner cần thiết trong scope.
Nó in một kết quả để đối chiếu trực tiếp với source.
6. Lỗi thường gặp
Lặp lại các biểu thức Boolean tương đương thay vì xây concept này từ concept kia có thể khiến compiler không nhận ra thứ tự mong muốn.
Hãy kiểm tra cả header, mức hỗ trợ thư viện C++20, lifetime và kiểu được suy luận.
7. Khi nào nên dùng
Nên dùng khi các overload tạo thành phân cấp tổng quát đến chuyên biệt thật sự.
Tránh dùng khi một hàm duy nhất với hành vi đơn giản sẽ rõ hơn phân cấp constraint.
8. Ví dụ đơn giản
Một overload nhận mọi integral, overload kia nhận named concept signed-integral cụ thể hơn. Tệp .cpp không nhận input nên kết quả dễ lặp lại.
Mã mẫu hoàn chỉnh
Tệp mã nguồn
cpp20/11_concept_subsumption_overload_resolution/main.cpp
// Day 11: Concept Subsumption and Overload Resolution
#include <concepts>
#include <iostream>
template<class T>
concept Integer = std::integral<T>;
template<class T>
concept SignedInteger = Integer<T> && std::signed_integral<T>;
void classify(Integer auto) {
std::cout << "integer\n";
}
void classify(SignedInteger auto) {
std::cout << "signed integer\n";
}
int main() {
classify(1);
classify(1u);
}
9. Điều cần nhớ
subsumptiondiễn đạt ý tưởng C++20 trung tâm của ngày này.Ví dụ cô lập một hành vi bằng dữ liệu cố định.
Compiler check không thay thế suy luận về lifetime và runtime.
Ưu tiên interface nhỏ nhất nói đúng yêu cầu thật.
10. Câu hỏi tự kiểm tra
Dễ — Nhiệm vụ chính của
subsumptiontrong ví dụ tối thiểu là gì?Trung bình — Overload nào được gọi với
int, và overload nào được gọi vớiunsigned int?Khó — Vì sao hai constraint mà con người thấy tương đương logic vẫn có thể không được sắp thứ tự nếu chúng là các atomic constraint riêng?