2012-10-17 51 views
11

我試着用google搜索這個沒有運氣,所以我在這裏嘗試。C++遞歸嵌套類型和名稱注入

我有幾個類,每個類定義一個成員struct foo。此成員類型foo本身可以繼承前一類,因此自己獲得成員類型foo

我想用模板元編程(見下文)來訪問嵌套foo類型,但C++名注射引入的問題,作爲上部foo類型名稱被注入到下foo類型,並且當我想上一個得到解決訪問較低的,比如說使用A::foo::foo

下面是一個例子:

#include <type_traits> 

struct A; 
struct B; 

struct A { 
    struct foo; 
}; 

struct B { 
    struct foo; 
}; 

struct A::foo : B { }; 
struct B::foo : A { }; 

// handy c++11 shorthand 
template<class T> 
using foo = typename T::foo; 

static_assert(std::is_same< foo< foo<A> >, foo<B> >::value, 
       "this should not fail (but it does)"); 

static_assert(std::is_same< foo< foo<A> >, foo<A> >::value, 
       "this should fail (but it does not)"); 

僅供參考,我實施功能衍生物,foo是微分型。上述情況發生在例如與sin/cos。

TLDR:我如何獲得foo<foo<A>>foo<B>而不是foo<A>

謝謝!

回答

1

這不是一個真正的自動解決方案,但解決了這個問題。您的 類型爲基類提供了一個typedef,通過SFINAE檢測到這個typedef的存在/不存在,並且通過基礎或通過正常查找找到嵌套的foo或者 。

如果您需要更多的自動化功能,您可以自動化has_base以檢查已知的 基本列表與is_base_of

#include <type_traits> 
template <typename T> 
struct has_base 
{ 
    typedef char yes[1]; 
    typedef char no[2]; 

    template <typename C> 
    static yes& test(typename C::base*); 

    template <typename> 
    static no& test(...); 

    static const bool value = sizeof(test<T>(0)) == sizeof(yes); 
}; 

struct A { 
    struct foo; 
}; 

struct B { 
    struct foo; 
}; 

struct A::foo : B { typedef B base; }; 
struct B::foo : A { typedef A base; }; 

template<typename T, bool from_base = has_base<T>::value > 
struct foo_impl { 
    typedef typename T::base::foo type; 
}; 

template<typename T> 
struct foo_impl<T, false> { 
    typedef typename T::foo type; 
}; 

template<typename T> 
using foo = typename foo_impl<T>::type; 

static_assert(std::is_same< foo< foo<A> >::, foo<B> >::value, 
       "this should not fail (but it does)"); 

static_assert(std::is_same< foo< foo<A> >, foo<A> >::value, 
       "this should fail (but it does not)"); 
int main() 
{ 

    return 0; 
} 
+0

我心中有類似的東西,但那種希望我能避免定義成員基本類型爲每個派生類型... 非常感謝反正! – max

+0

@MaximeTournier正如我所說:如果基地清單是固定的,你可以自動處理它們。面對多重繼承,這變得很奇怪。 – pmr

+0

明白了,但基地的名單是可悲的不固定: -/ – max