Per [meta.rel] (20.10.6 в С++ 14), для типа класса T, std::is_base_of<T,T> - true, но для встроенного типа T, std::is_base_of<T,T> - false, Говоря по-разному, типы классов являются основами самих себя, но встроенных типов нет. Какова мотивация/полезность этой разницы в лечении?
Почему std:: is_base_of <T, T> true, когда T является типом класса, но false, когда T является встроенным типом?
Ответ 1
Обоснование вернулось довольно далеко, и оно плохо документировано.
is_base_of изначально назывался is_base_and_derived и был введен в TR1. Дейв Абрахамс представил проблему против этого класса в N1541, номер 3.13:
В настоящее время
is_base_and_derived<X,Y>возвращает false, когдаXиYодинаковы. Это технически правильно (Xне является собственной базой класс), но это не полезно. Определение следует ослабить return true, когдаXиYсовпадают, даже если тип isnt фактически класс.
К сожалению, проблема не объясняет, почему это определение не полезно. Однако точка зрения не была уникальной в то время (2003). Andrei Alexandrescu Modern С++ Design, опубликованный двумя годами ранее, имел одинаковую черту и почти тот же комментарий в разделе 2.7 о его макросе SUPERSUBCLASS, хотя в этой книге также добавлено обходной макрос, если вы действительно не хотите, чтобы класс считался его собственной базой.
Современный дизайн С++ продолжает использовать SUPERSUBCLASS в разделе 3.12, чтобы заказать Typelist в порядке наследования. Глубоко в деталях этого упражнения, тот факт, что SUPERSUBCLASS(T, T) является истинным, используется (для удобства реализации).
К 2004 году отчет TR1, N1647, принял понятие о том, что std::is_base_of<T,T>::value == true был полезен, когда T является классом типа non-union.
N2255 дополнительно разъясняет, как is_base_of должен работать для неклассических типов, и это изменение привело к формулировке, которую вы видите сегодня. Однако существуют обширные редакционные различия между тем, что предлагает эта принятая статья, и тем, что было создано в следующем проекте (N2284). Мое мнение таково, что редактор значительно улучшил формулировку.
Недокументированное обоснование того, почему N2255 создало разделение между типами неединичных классов и всего остального, состоит в том, что is_base_of исторически ответил на вопросы о иерархии наследования типы, с только удобным "трюком", что класс можно считать собственной базой через анализ "is-a". Однако типы, которые не могут участвовать в отношениях наследования, никогда не должны квалифицироваться как базовые классы, согласно многочисленным авторам этого признака.
Был ли это лучший дизайн для обсуждения. Однако есть достаточные черты (например, is_class и is_same), чтобы создавать все, что вам нужно, из этих основных черт.
Это скорее история, а не просто "почему". Однако точка этого ответа состоит в том, чтобы вызывать, что is_base_of развивалось в течение большого количества времени, через многие итерации. И каждая итерация ощущалась в то время как эволюционное улучшение того, что было раньше.
И все это сводится к: Это спецификация, которую комитет считал наиболее полезной. Но поскольку спецификация и дизайн развивались на протяжении многих лет, и через нескольких авторов, нет хорошего общего дизайнерского документа или обоснования.
Ответ 2
Встроенные типы не являются классами, а вещи, которые не являются классами, не могут быть основой чего-либо.
Если что-то меня несколько удивляет тем, что std::is_base_of<T,T> истинно даже для типов классов, но это, вероятно, отношение "можно рассматривать как" для классов.
Мех, я не знаю.