昨天遇到了如何从某个类获取所有基类的问题。 例如:
class Object
{
public:
Object() = default;
};
class DerivedOne
: public Object
{
public:
DerivedOne() = default;
};
class DerivedTwo
: public Object
, public DerivedOne
{
public:
DerivedTwo() = default;
};
我想在typelist =>中获取DerivedTwo的所有基类; {Object,DerivedOne,Object} 需要多次拒绝来自Object类的继承。
有人有这样的经验或知识怎么做?
答案 0 :(得分:0)
评论中提到了TR2反射提案,该提案已“被放弃”,但已在gcc中实现。下面的代码基于SO帖子:Finding base class at compile time
#include<tr2/type_traits>
template<typename T>
struct types_as_tuple;
template<typename... Ts>
struct types_as_tuple<std::tr2::__reflection_typelist<Ts...>>
{
typedef std::tuple<Ts...> type;
};
template<typename T>
struct duplicate_type;
template<typename T1, typename T2, typename... Ts>
struct duplicate_type<std::tuple<T1, T2, Ts...>> {
constexpr static bool value = std::is_same<T1, T2>::value
|| duplicate_type<std::tuple<T1, Ts...>>::value;
|| duplicate_type<std::tuple<T2, Ts...>>::value
};
template<typename T1, typename T2>
struct duplicate_type<std::tuple<T1, T2>> {
constexpr static bool value = std::is_same<T1, T2>::value;
};
template<typename T>
struct TypesPrinter;
template<typename T>
struct TypesPrinter<std::tuple<T>> {
constexpr TypesPrinter() {
std::cout << typeid(T).name() << ' ';
}
};
template<typename T, typename... Ts>
struct TypesPrinter<std::tuple<T, Ts...>> {
constexpr TypesPrinter() {
TypesPrinter<std::tuple<T>>();
TypesPrinter<std::tuple<Ts...>>();
}
};
struct A {};
struct B: A {};
struct C {};
struct D : B, C, A {};
int main() {
//---------------------------------------------------------------
// getting all direct and indirect bases of a class with TR2
//---------------------------------------------------------------
using bases_of_D = types_as_tuple<std::tr2::bases<D>::type>::type;
//---------------------------------------------------------------
// checking for duplication at compile time
// (can also use static_assert)
//---------------------------------------------------------------
if constexpr(duplicate_type<bases_of_D>::value) {
std::cout << "duplicate base in class D" << std::endl;
}
//---------------------------------------------------------------
// printing the types
//---------------------------------------------------------------
TypesPrinter<bases_of_D>();
}