[英]std::is_base_of() depth
我有这样的层次结构:
namespace MyService{
class IBase
{
public:
virtual ~IBase(){}
protected:
IPointer *_somePointer;
};
}
class IInterface: public MyService::IBase
{
public:
virtual ~IInterface(){}
virtual std::string get() const = 0;
};
class ConcreteClass: public IInterface
{
public:
std::string get() const
{
bool isNull = (_somePointer == NULL);
return "Hello";
}
};
bool isBase = std::is_base_of<IBase, ConcreteClass>::value;
我需要检查的是I3是从I1派生的。 但是std :: is_base_of()对我来说不太好-它返回false。 目标是将任何类添加到IBase中,并检查层次结构中是否存在IBase
找到了问题,但没有解决。 我的代码是:
template<class Base, class Derived>
bool IsDerivedFromBase()
{
if( std::tr1::is_fundamental<Base>::value )
throw MyService::Exceptions::ETypeTraitsInvalidArgument( "Base class can't be POD" );
if( std::tr1::is_fundamental<Derived>::value )
throw MyService::Exceptions::ETypeTraitsInvalidArgument( "Derived class can't be POD" );
bool a = std::tr1::is_base_of<Base, Derived>::value;
return a;
}
我有一个这样的
bool a = std::is_base_of<MyService::IBase, SomeInterface>::value; // true
a = IsDerivedFromBase<MyService::IBase, SomeInterface>(); // false
对于G ++ 4.7,这的确输出true
:
class I1{};
class I2: public I1{};
class I3: public I2{};
int main(int argc, const char* argv[])
{
std::cout << std::boolalpha
<< std::is_base_of<I1, I3>::value
<< std::endl;
return 0;
}
请注意, std::is_base_of<I1, I3>::value
等效于实例化类型为std::is_base_of<I1, I3>
的对象并将其转换为bool
。
我相信这样做是正确的。 std::is_base_of<Base, Derived>
被定义为具有条件(§20.9.6):
Base
是Derived
(10)的基类,与cv限定词无关,或者Base
和Derived
不是联合,并且在不考虑cv-qualifier的情况下,命名相同的类类型
基类的定义如下(第10节):
一类
B
是一个基类的类的D
,如果它是直接基类的D
或直接基类中的一个的D
的基类。
所以是的, I1
是I3
的基类,并且std::is_base_of<I1, I3>::value
应该为true
。
#include <iostream>
#include <type_traits>
class A {};
class B : public A {};
class C : public B {};
int main() {
std::cout << std::boolalpha;
std::cout << "a2b: " << std::is_base_of<A, B>() << '\n';
std::cout << "b2a: " << std::is_base_of<B, A>() << '\n';
std::cout << "c2b: " << std::is_base_of<C, B>() << '\n';
std::cout << "a2c: " << std::is_base_of<A, C>() << '\n';
}
产量:
a2b: true
b2a: false
c2b: false
a2c: true
以上适用于GCC 4.6和4.7。 如果您正在使用其他内容,则需要指定。
您的错误必须在其他地方。
我找到问题了。 我有一些带有单元测试的.cpp文件,其中我在本地定义了具有相同名称的类。 尚未在标准tis中找到,但是重现代码类似于:
/// 1.cpp
class IInterface{};
class Interface: public IInterface{};
/// class 2.cpp
class IInterface: public MyService:IBase{};
class Interface: public IInterface{};
/// facility.h
namespace a{ namespace b{
template<class T, class B>
bool IsBaseOf(){
return std::is_base_of<T, B>();
}
}
}
}
/// ...main
a::b::IsBaseOf<MyService::IBase, Interface>();
它应该/可能失败。 但是,如果我使类名唯一,那就好了。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.