11

我尝试在没有运气的情况下使用谷歌搜索,所以我在这里尝试。

我有几个类,每个类都定义一个 member 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>

谢谢 !

4

1 回答 1

1

这不是真正的自动解决方案,但可以解决问题。您的类型为基类提供 typedef,此 typedef 的缺失/存在通过 SFINAE 检测,嵌套 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;
}
于 2012-10-17T16:12:04.077 回答