Мне нужна черта типа, которая будет истинна, если данный тип получен из чего-либо, а false в противном случае.
Например:
template<class T>
struct is_inherit
//... logic of inheritance detection
;
template<class T>
void AppLogic(){
if constexpr(is_inherit<T>::value) {
puts("T has base");
//...
} else {
puts("T doesn't have base");
//...
}
}
struct A {};
struct C {};
struct B: C {};
int main() {
AppLogic<A>(); // print: T doesn't have base
AppLogic<B>(); // print: T has base
}
Можно ли каким-то образом реализовать эту структуру атрибутов "is_inherit"?
Почему?
Я разрабатываю компоновщик фреймов вручную для Windows x64. Согласно документации https://docs.microsoft.com/en-us/cpp/build/return-values-cpp, если тип:
- имеет длину 1, 2, 4, 8, 16, 32 или 64 бит;
- не имеет определенного пользователем конструктора, деструктора или оператора присваивания копии;
- не имеет частных или защищенных нестатических элементов данных;
- не имеет нестатических элементов данных ссылочного типа;
- не имеет базовых классов;
- не имеет виртуальных функций;
- и не имеет данных, которые также не отвечают этим требованиям;
то его возвращаемое значение находится в регистре RAX, иначе функция имеет скрытый аргумент, который я должен обнаружить и обработать.
Это было определение С++ 03 POD, однако в С++ 11 это изменилось:
Поскольку определение было изменено в стандарте С++ 11, мы не рекомендуем использовать
std::is_pod
для этого теста.
До сих пор с некоторыми сопряженными признаками я мог обнаружить, соответствует ли тип определению С++ 03 POD или нет. Однако с С++ 17 общие правила изменились, и это нарушило мое решение.
Если я могу каким-то образом определить, имеет ли тип T какой-либо базовый класс, мое решение снова будет работать.