2

我正在尝试制作一个通用代码,如果 B 不是 D 的祖先,则会导致编译错误。我想出了:

template<typename B, typename D>
struct assert_base_of {
    enum {value = sizeof(B::D)};
}

它不起作用。当我这样“调用”它时:

assert_base_of<A2,A1>::value;

我收到以下错误(g++ 4.8.2):

main.cpp:16:22: error: ‘D’ is not a member of ‘A2’

看起来模板参数 D 没有被 A1 取代。任何人都可以解释并提出解决方案吗?

4

1 回答 1

3

继承不会将派生类封闭到基类的范围内,因此为此使用范围解析运算符是没有意义的。正确的替代方法(也适用于多重继承)是滥用重载解决规则:

#include <iostream>
#include <type_traits>

template<typename Base, typename Derived,
       bool = std::is_same<Base, Derived>::value>
struct is_base_of_impl
{

  typedef typename std::remove_cv<Base>::type     no_cv_base;      
  typedef typename std::remove_cv<Derived>::type  no_cv_derived;


  template<typename _Up>
  static std::true_type test(no_cv_derived&, _Up);
  static std::false_type test(no_cv_base&, int);

  //Black Magic
  struct converter
  {
   operator no_cv_derived&();
   operator no_cv_base&() const;
  };

  static const bool value = decltype(test(converter(), 0))::value;
};

template<typename Base, typename Derived>
struct is_base_of_impl<Base, Derived, true>
{ 
    static const bool value = std::is_same<Base, Derived>::value; 
};

template<typename Base, typename Derived>
struct is_base_of
: public std::integral_constant<bool,
               is_base_of_impl<Base, Derived>::value>
{ };


struct A {};
struct B1 : A {};
struct B2 : A {};
struct C : B1, B2 {};

int main()
{
    std::cout << is_base_of<A, B1>::value << "\n";
    std::cout << is_base_of<B1, C>::value << "\n";
    std::cout << is_base_of<A, C>::value << "\n";
    return 0;
}

有关更多信息,请查看以下链接:

`is_base_of` 是如何工作的?

https://groups.google.com/d/msg/comp.lang.c++.moderated/xv4VlXq2omE/--WAroYkW2QJ

于 2015-06-20T13:12:53.867 回答