Tôi đang cố gắng hiểu những gì siêu lập trình nói chung và những gì nó có trong C ++ nói riêng
Bạn chưa nói những gì bạn hiểu bằng cách lập trình siêu hình nói chung , vì vậy câu trả lời của bạn không có điểm bắt đầu chung.
Tôi sẽ giả định định nghĩa wikipedia là đủ tốt cho việc này:
Metaprogramming là một kỹ thuật lập trình trong đó các chương trình máy tính có khả năng coi các chương trình khác là dữ liệu của chúng.
... có thể được sử dụng để di chuyển các tính toán từ thời gian chạy sang thời gian biên dịch, để tạo mã bằng cách sử dụng tính toán thời gian biên dịch ...
C ++ thường không cho phép tự sửa đổi mã, vì vậy tôi bỏ qua điều đó. Tôi cũng chọn không tính bộ tiền xử lý, vì thời gian biên dịch văn bản tại (hoặc được cho là ngay trước đó) thời gian biên dịch không giống như hoạt động trên ngữ nghĩa của chương trình.
Câu hỏi của tôi là nếu tất cả các cách sử dụng mẫu trong C ++ được phân loại là siêu lập trình
Không có nó không phải là.
Xem xét, để tham khảo:
#define MAX(a,b) ((a) > (b) ? (a) : (b))
đó là cách lỏng lẻo để viết một hàm chung (loại bất khả tri) max
mà không sử dụng các mẫu. Tôi đã nói rằng tôi không coi bộ tiền xử lý là siêu lập trình, nhưng trong mọi trường hợp, nó luôn tạo ra mã giống hệt nhau bất cứ khi nào nó được sử dụng.
Nó chỉ đơn giản là ủy thác phân tích mã đó, và lo lắng về các loại và liệu có a>b
được xác định cho trình biên dịch hay không, trong giai đoạn dịch sau . Không có gì ở đây hoạt động vào thời gian biên dịch để tạo mã kết quả khác nhau tùy thuộc vào ... bất cứ điều gì. Không có gì, tại thời gian biên dịch, được tính toán.
Bây giờ, chúng ta có thể so sánh phiên bản mẫu:
template <typename T>
T max(T a, T b) { return a > b ? a : b; }
Điều này không chỉ đơn giản là thực hiện một sự thay thế văn bản. Quá trình khởi tạo phức tạp hơn, các quy tắc tra cứu tên và quá tải có thể được xem xét và trong một số trường hợp, các khởi tạo khác nhau có thể không tương đương về mặt văn bản (ví dụ: một người có thể sử dụng bool ::operator< (T,T)
và một bool T::operator<(T const&)
hoặc bất cứ điều gì).
Tuy nhiên, ý nghĩa của mỗi khởi tạo là như nhau (giả sử các định nghĩa tương thích về operator<
các loại khác nhau, v.v.) và không có gì được tính toán tại thời điểm biên dịch ngoài quy trình giải quyết các loại và tên thông thường của máy tính.
Bên cạnh đó, chắc chắn chương trình của bạn chứa các hướng dẫn để trình biên dịch nói cho nó biết phải làm gì , bởi vì đó là tất cả các chương trình.
Bây giờ, có những trường hợp cận biên như
template <unsigned N>
struct factorial() { enum { value = N * factorial<N-1>::value }; };
mà làm di chuyển một tính toán đến thời gian biên dịch (và trong trường hợp này một tổ chức phi chấm dứt một kể từ khi tôi không thể bị làm phiền để viết trường hợp thiết bị đầu cuối), nhưng được cho là không lập trình meta.
Mặc dù định nghĩa Wikipedia đã đề cập đến việc tính toán chuyển sang thời gian biên dịch, đây chỉ là một tính toán giá trị - nó không đưa ra quyết định về thời gian biên dịch về cấu trúc hoặc ngữ nghĩa của mã của bạn.