2015-02-23 20 views
14

Mỗi [meta.rel] (20.10.6 trong C++ 14), đối với loại lớp T, std::is_base_of<T,T> là đúng, nhưng đối với loại được cài sẵn T, std::is_base_of<T,T> là sai. Nói một cách thông tục, các loại lớp là cơ sở của bản thân, nhưng các kiểu tích hợp thì không. Động lực/tiện ích cho sự khác biệt này trong điều trị là gì?Tại sao std :: is_base_of <T, T> đúng khi T là một loại lớp, nhưng sai khi T là một kiểu dựng sẵn?

Trả lời

2

Các loại được tạo sẵn không phải là các lớp và những thứ không phải là lớp học không thể là cơ sở của mọi thứ.

Nếu bất cứ điều gì tôi hơi ngạc nhiên rằng std::is_base_of<T,T> là đúng ngay cả đối với các loại lớp học, nhưng đó có thể là mối quan hệ "có thể được coi là" cho các lớp học.

Meh, tôi không biết.

+0

Nếu bạn cần 'T' là một kiểu nhất định hoặc bắt nguồn từ nó,' std :: is_base_of' biểu thị chính xác. Nếu nó không phản xạ, bạn hầu như luôn luôn phải sử dụng nó với 'std :: is_same'. Ngoài ra, hầu hết các hệ thống có phân nhóm sử dụng tính phản xạ. – DanielKO

+0

@DanielKO: Như mọi thứ hiện tại, tôi nghi ngờ rằng trong một số trường hợp, bạn sẽ phải sử dụng 'std :: is_fundamental' trước khi áp dụng' std :: is_base_of' để đối phó với thực tế là các kiểu cơ bản và lớp là được xử lý khác bởi 'std :: is_base_of'. Điều không rõ ràng là những gì bất đối xứng mua cho bạn. – KnowItAllWannabe

+0

@DanielKO: Tuy nhiên đối với một số loại _it not_. –

23

Lý do cơ bản quay trở lại một cách hoàn toàn và không được ghi chép đầy đủ.

is_base_of ban đầu được gọi là is_base_and_derived và được giới thiệu trong TR1. Dave Abrahams giới thiệu một vấn đề đối với lớp này trong N1541, số 3.13:

Hiện nay, is_base_and_derived<X,Y> lợi nhuận sai khi XY đều giống nhau. Điều này là chính xác về mặt kỹ thuật (X không phải là lớp cơ sở riêng của mình ), nhưng nó không hữu ích. Định nghĩa phải được nới lỏng thành trả về true khi XY giống nhau, ngay cả khi loại không phải là thực sự là một lớp.

Rất tiếc, vấn đề không giải thích được tại sao định nghĩa đó không hữu ích. Tuy nhiên quan điểm không phải là duy nhất vào thời điểm đó (2003). Andrei Alexandrescu's Modern C++ Design xuất bản hai năm trước đó có nhiều đặc điểm giống nhau, và nhiều nhận xét tương tự trong phần 2.7 về macro của nó SUPERSUBCLASS, mặc dù cuốn sách này cũng thêm một macro workaround nếu bạn thực sự không muốn một lớp được coi là cơ sở riêng của nó.

Modern C++ Design tiếp tục sử dụng SUPERSUBCLASS trong phần 3.12 để đặt hàng một Typelist theo thứ tự kế thừa. Sâu trong các chi tiết của bài tập này, thực tế là SUPERSUBCLASS(T, T) là đúng là lợi dụng (để thuận tiện trong việc thực hiện).

Năm 2004, TR1 report, N1647, đã chấp nhận khái niệm std::is_base_of<T,T>::value == true hữu ích khi T là loại không phải là loại công đoàn.

N2255 làm rõ thêm cách is_base_of được cho là hoạt động đối với các loại không phải lớp và thay đổi này dẫn đến từ ngữ mà bạn thấy ngày hôm nay. Tuy nhiên, có những khác biệt biên tập rộng lớn giữa những gì giấy được chấp nhận này đề xuất và những gì được sản xuất trong bản nháp sau (N2284). Ý kiến ​​của tôi là biên tập viên đã cải thiện rất nhiều từ ngữ.

Lý do không có giấy tờ cho lý do tại sao N2255 tạo ra một sự phân chia giữa các loại lớp phi công đoàn và mọi thứ khác là is_base_of lịch sử đã trả lời câu hỏi về hệ thống phân cấp thừa kế các loại, với chỉ một "lừa" thuận tiện mà một lớp có thể được coi riêng của mình căn cứ thông qua phân tích "is-a".Tuy nhiên các loại không thể tham gia vào một mối quan hệ thừa kế không bao giờ nên đủ điều kiện làm lớp cơ sở, theo nhiều tác giả của đặc điểm này.

Có hay không đó là thiết kế tốt nhất là để tranh luận. Tuy nhiên, có đủ các đặc điểm (ví dụ: is_classis_same) để xây dựng bất cứ điều gì bạn cần từ những đặc điểm cơ bản này.

Đây là một lịch sử hơn là một "lý do" thẳng thắn. Tuy nhiên, điểm của câu trả lời này là để gọi ra rằng is_base_of phát triển qua rất nhiều thời gian, thông qua nhiều lần lặp lại. Và mỗi lần lặp lại được cảm nhận vào thời điểm đó là một cải tiến tiến hóa về những gì đã có trước đó.

Và tất cả đều tóm tắt: Đây là thông số mà ủy ban nghĩ là hữu ích nhất. Nhưng khi thiết kế số & được cải tiến trong nhiều năm và thông qua một số tác giả, không tồn tại tài liệu thiết kế tổng thể hay lý do cơ bản nào tốt.

+0

Bạn không thể viết 'class Foo: int {};' cho bất kỳ 'Foo' nào. Vì vậy, mặc dù một 'int' là-một' int' Bạn vẫn không thể có một hệ thống phân cấp liên quan và 'int'. Hừm. (Ngoài ra, đây có thể là cách hay để viết typedef). – emsr

Các vấn đề liên quan