检测普通基类
Detect common base class
假设一个人具有类层次结构,没有多个继承:
struct TOP{};
struct L : TOP{};
struct R : TOP{};
struct LL : L{};
struct LR : L{};
struct RL : R{};
struct RR : R{};
是否可以编写将返回两种类型的共同基础类型的元功能?(如果不存在常见的基类,它可以返回void
。(例如
common_base<RR, R>::type == R
common_base<RL, RR>::type == R
common_base<LL, RR>::type == TOP
common_base<LL, std::string>::type == void
显然,这与多次侵犯无法使用,但我专注于单个继承情况。
首先,如果没有基础类的内省,这似乎是不可能的。因此,我有一个更容易的问题,以这样的方式进行操作,以使每个clase知道其基础(通过内部base
类型(,例如:
struct LR : L{using base = L;};
即使以这种方式,我似乎也无法正确处理元编程。
我也在某个地方阅读(我现在找不到(,因为GCC有一些扩展名检测公共基类。是吗?
std :: tr2中的某个点碱基和 direct_bases
,但不包括在内。某些版本的海湾合作委员会具有它。使用这些也许您可以得到想要的东西。
如果每个类都别名为 base
(如下(,可以完成。
struct Child : Parent { using base = Parent; }; //typedef works too
我创建了一个struct
:
template <class T1, class T2>
struct CommonBase;
CommonBase
通过将T2
的每个基础与T1
进行比较。当它达到顶级基础时,它再次从底部开始,但与T1
的基础进行比较。
例如:CommonBase<RL, RR>
将通过以下检查:
RL != RR
RL != R
RL != Top
R != RR
R == R
所以CommonBase<RL, RR>::type == R
。如果没有共同的基础,则type == void
。
我将代码放在最后,因为模板元编程非常漂亮:
#include <type_traits>
template <class T>
struct GetBase //type = T::base, or else void
{
template <class TT> static typename TT::base& f(int);
template <class TT> static void f(...);
typedef std::remove_reference_t<decltype(f<T>(0))> type;
};
template <class T1, class T2>
struct Compare2 //Compares T1 to every base of T2
{
typedef typename GetBase<T2>::type _type;
template <class T, bool = !std::is_same<T, void>::value>
struct helper
{
typedef typename Compare2<T1, T>::type type;
};
template <class T>
struct helper<T, false>
{
typedef void type;
};
typedef typename helper<_type>::type type;
};
template <class T>
struct Compare2<T, T>
{
typedef T type;
};
template <class T1, class T2>
struct Compare1 //Uses Compare2 against every base of T1
{
typedef typename GetBase<T1>::type _type;
template <class T, bool = !std::is_same<T, void>::value>
struct helper
{
typedef typename Compare1<T, T2>::type type;
};
template <class T>
struct helper<T, false>
{
typedef void type;
};
typedef std::conditional_t<std::is_same<typename Compare2<T1, T2>::type, void>::value, typename helper<_type>::type, typename Compare2<T1, T2>::type> type;
};
template <class T>
struct Compare1<T, T> //Probably redundant
{
typedef T type;
};
template <class T1, class T2>
struct CommonBase //You can throw a std::enable_if on this to limit it to class types
{
typedef typename Compare1<T1, T2>::type type;
};
在这里您可以在某些测试用例上看到它。
相关文章:
- std::具有相同基类的类的变体
- 是否可以初始化不可复制类型的成员变量(或基类)
- 在C++中,是否可以基于给定的标识符创建基类的新实例,反之亦然
- 基类中的函数名称解析
- C++初始化基类
- 如何通过派生类函数更改基类中的向量
- 如何定义一个纯抽象基类
- 如何使用基类指针引用派生类成员
- 使用基类模板检测is_base_of
- 有没有一种方法可以使用SFINAE来检测一个类型是否实现了给定的抽象基类
- 检测普通基类
- 当试图检测基类是否具有虚拟破坏者时,如何获取正确的编译器错误消息
- 检测我们是在子类还是基类中
- 检测(可能是抽象的)基类的受保护构造函数
- 使用sfinae来检测可变模板的基类是否有特定的方法
- 检测 CRTP 基类的同级
- 检测基类对指向派生类的引用的赋值
- 如何在编译时检测基类的模板参数(针对错误)
- 如何将类传递给方法,并从基类检测继承者
- 检测继承类并将其转换为基类