获取CRTP继承链中最深的类 [英] Get deepest class in CRTP inheritance chain

查看:27
本文介绍了获取CRTP继承链中最深的类的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想知道如何解决以下问题(C++17):假设有几个模板类,它们以类似 CRTP 的方式相互继承(仅单继承).对于给定的实例化模板基类,找到在继承链中距离它最远的类.

I would like to know how to solve the following problem (C++17): suppose there are several template classes, inherited from each other in CRTP-like fashion (single inheritance only). For a given instantiated template base class, find the class that is furthest from it down the inheritance chain.

我一开始以为这应该很容易,但没能做到.

I first thought that is should be pretty easy, but was not able to accomplish this.

为了简化,假设每个根和每个中间类在其 public 区域中都有 using DerivedT = Derived.

To simplify, suppose that every root and every intermediate class has using DerivedT = Derived in its public area.

示例:

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;
...

我尝试过的第一个实现:

First implementation I've tried:

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>;
};

我尝试过的第二个实现:

Second implementation I've tried:

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>()));
};

它们都没有编译.

第一个 -- 因为 GetDeepest<T> 在语句 using Type = ... 中的类型不完整,第二个是因为使用 auto 作为返回类型.

First one -- because of incomplete type of GetDeepest<T> in statement using Type = ..., second because of recursive call of a function with auto as a return type.

是否有可能实现具有此类属性的 GetDeepest 类?现在我很好奇,即使这可能不是实现我想要的最佳方式.

Is it even possible to implement GetDeepest<T> class with such properties? Now I'm very curious, even if it might be not the best way to accomplish what I want.

谢谢!

推荐答案

我不确定我是否完全理解这个问题,所以请随时在评论中问我.

I'm not sure if I fully understand the question so feel free to ask me in comments.

但我认为这应该可行:

#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);

}

这篇关于获取CRTP继承链中最深的类的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆