获取 CRTP 继承链中最深的类
Get deepest class in CRTP inheritance chain
我想知道如何解决以下问题(C++17(:假设有几个模板类,它们以类似 CRTP 的方式相互继承(仅限单个继承(。对于给定的实例化模板基类,在继承链中查找离它最远的类。
我最初认为这应该很容易,但无法做到这一点。
为了简化起见,假设每个根和每个中间类在其public
区域中都有using DerivedT = Derived
。
例:
template <class T>
struct GetDeepest {
using Type = ...;
};
template <class T>
struct A {
using DerivedT = T;
};
template <class T>
struct B : public A<B<T>> {
using DerivedT = T;
};
struct C : B<C> {
};
struct D : A<D> {
};
GetDeepest<A<D>>::Type == D;
GetDeepest<B<C>>::Type == C;
GetDeepest<A<B<C>>>::Type == C;
...
我尝试过的第一个实现:
template <class T>
struct GetDeepest {
template <class Test, class = typename Test::DerivedT>
static std::true_type Helper(const Test&);
static std::false_type Helper(...);
using HelperType = decltype(Helper(std::declval<T>()));
using Type = std::conditional_t<std::is_same_v<std::true_type, HelperType>,
GetDeepest<typename T::DerivedT>::Type,
T>;
};
我尝试过的第二个实现:
template <class T>
struct HasNext {
template <class Test, class = typename Test::DerivedT>
static std::true_type Helper(const Test&);
static std::false_type Helper(...);
using HelperType = decltype(Helper(std::declval<T>()));
static const bool value = std::is_same_v<std::true_type, HelperType>;
};
template <class T>
auto GetDeepestHelper(const T& val) {
if constexpr(HasNext<T>::value) {
return GetDeepestHelper(std::declval<typename T::DerivedT>());
} else {
return val;
}
}
template <class T>
struct GetDeepest {
using Type = decltype(GetDeepestLevelHelper(std::declval<T>()));
};
它们都不编译。
第一个 -- 因为语句 using Type = ...
中GetDeepest<T>
类型不完整,第二个是因为递归调用以 auto
作为返回类型的函数。
甚至可以实现具有此类属性GetDeepest<T>
类吗?现在我很好奇,即使这可能不是实现我想要的最好方法。
谢谢!
我不确定我是否完全理解这个问题,所以请随时在评论中问我。
但我认为这应该有效:
#include <type_traits>
template<typename T>
struct GetDeepest
{
using Type = T;
};
template<template<typename> class DT, typename T>
struct GetDeepest<DT<T>>
{
using Type = typename GetDeepest<T>::Type;
};
template <class T>
struct A {
using DerivedT = T;
};
template <class T>
struct B : public A<B<T>> {
using DerivedT = T;
};
struct C : B<C> {
};
struct D : A<D> {
};
int main()
{
static_assert(std::is_same<GetDeepest<A<D>>::Type, D>::value);
static_assert(std::is_same<GetDeepest<B<C>>::Type, C>::value);
static_assert(std::is_same<GetDeepest<A<B<C>>>::Type, C>::value);
}
相关文章:
- 继承函数的重载解析
- 继承期间显示未知行为的子类
- 头文件-继承c++
- 为什么在保护模式下继承升级不起作用
- 通过继承类使用来自不同命名空间的运算符
- 子目录是否继承属性,例如add_definitions,include_directories和父Cmakelist.t
- 尝试使用继承和模板实现CRTP.Visual Studio正在生成编译器错误
- 将实现从继承的 CRTP 注入到继承的接口类
- 使用 CRTP 进行选择性静态成员继承
- 仅函数的多重继承 - 没有虚拟和 CRTP
- 有没有一种干净(更)的方法将 CRTP 与可变参数继承混合在一起?
- 获取 CRTP 继承链中最深的类
- CRTP 和复制/移动赋值/构造函数继承
- C++泛型编程 CRTP 基类继承自派生类型提供的类
- 使用继承时,带有 CRTP 的类型定义不起作用
- 通过CRTP类继承的模板化派生类,访问基类成员对象
- 重载CRTP和其他模板的继承
- CRTP 继承中的基类"friending"是否也会影响子类?
- 带有继承历史的CRTP插件自动注册(尝试使用SFINAE,但失败)
- c++中的多级继承(CRTP)