std::is_base_of() depth

std::is_base_of() depth

本文关键字:depth base is std of      更新时间:2023-10-16

我有一个这样的层次结构:

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):

BaseDerived(10)的基类,而不考虑cv-限定符,或者BaseDerived不是并集,并且命名相同的类类型,而不考虑cv-限定符

基类定义如下(§10):

B是类D的基类,如果它是D的直接基类或D的一个基类的直接基类

所以是的,I1I3的基类,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文件,我在其中定义了具有相同名称的本地类。还没有在标准中找到,但是复制代码类似于:

/// 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>();

它应该/可以失败。但是如果我让类名唯一,那就没问题了