如何检测类型是否是另一种类型的可见基础?
问题描述:
如果我这样做
struct A{};
struct C:private A{};
typedef char (&yes)[1];
typedef char (&no)[2];
template <typename B, typename D>
struct Host
{
operator B*() const;
operator D*();
};
template <typename B, typename D>
struct is_base_of
{
template <typename T>
static yes check(D*, T);
static no check(B*, int);
static const bool value = sizeof(check(Host<B,D>(), int())) == sizeof(yes);
};
int main(){
std::cout<<is_base_of<A,C>::value<<std::endl;
}
我得到1.我想在 C
是私人 A
,以及当 C
是公开 A
。
I get a 1. I would like to get a 0 when C
is a private A
, and a 1 when C
is a public A
.
[代码派生自 is_base_of如何工作?]
答
您是否可以访问具有C ++ 11支持的编译器?
Do you have access to a compiler with C++11 support?
如果是这样,您可以将Chad使用 static_cast
与 decltype
创建一个非常简单的类型trait实现(如此问题)。根据Jonathan Wakely的建议,当 D
定义运算符B&()$ c $时,引用被替换为指针以避免假阳性c>。
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 {};
使用gcc 4.7时:
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;
}