How can I detect whether a type is a visible base of another type?

后端 未结 3 1298
夕颜
夕颜 2021-02-19 17:29

If I do

struct A{};
struct C:private A{};

typedef char (&yes)[1];
typedef char (&no)[2];

template 
struct Host
{
 operato         


        
相关标签:
3条回答
  • 2021-02-19 18:00

    Do you need something that can be evaluated at runtime, or will a simple compile time error suffice?

    struct A {};
    struct B : private A {};
    
    int main()
    {
       B b;
    
       // gives error C2243: 'static_cast' : conversion from 'B *' to 'A &' exists, but is inaccessible
       A& a = static_cast<A&>(b);
    
       return 0;
    }
    
    0 讨论(0)
  • 2021-02-19 18:07

    In order to apply the compile-time overload resolution trick to detect access specifiers, you would at least need that access specifiers are considered at the time overload resolution is done. This is not the case with C++03, so it cannot be done. I believe C++11 changes this so with some artificial conversions and SFINAE you would be able to implement it.

    Update: I'm going over n3242 Overload Resolution section, and I cannot find anything that would indicate that access specifiers are considered for overload resultion at C++11.

    0 讨论(0)
  • 2021-02-19 18:12

    Do you have access to a compiler with C++11 support?

    If so, you can combine Chad's use of static_cast with decltype to create a very simple type trait implementation (as demonstrated in this question). As per Jonathan Wakely's suggestion, the references have been replaced with pointers to avoid false positives when D defines an operator B&().

    template<typename> struct AnyReturn { typedef void type; };
    
    template<typename B, typename D, typename Sfinae = void>
    struct is_base_of: std::false_type {};
    
    template<typename B, typename D>
    struct is_base_of<B, D,
        typename AnyReturn< decltype( static_cast<B*>( std::declval<D*>() ) ) >::type
    >: std::true_type {};
    

    When using gcc 4.7:

    struct Base {};
    struct PublicDerived  : public  Base {};
    struct PrivateDerived : private Base {};
    
    int main()
    {
        std::cout << is_base_of<Base, PublicDerived >::value << std::endl; // prints 1
        std::cout << is_base_of<Base, PrivateDerived>::value << std::endl; // prints 0
        return 0;
    }
    
    0 讨论(0)
提交回复
热议问题