2012-10-17 38 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