簡體   English   中英

獲得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);

}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM