1

我有这样的层次结构:

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() 对我来说效果不佳 - 它返回错误。目标是添加到任何类 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
4

3 回答 3

4

这确实true与 G++ 4.7 一起输出:

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 限定符,或者Base不是Derived联合,并且命名相同的类类型而不考虑 cv 限定符

基类是这样定义的(§10):

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

所以是的,I1是的基类,I3应该std::is_base_of<I1, I3>::valuetrue

于 2013-02-26T13:30:25.107 回答
2

不,代码有效:

#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。如果您使用的是其他东西,则需要指定它。

您的错误必须在其他地方。

于 2013-02-26T13:31:06.743 回答
0

我发现了问题。我有一些带有单元测试的 .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>();

它应该/可能会失败。但是,如果我使类名独一无二,那也没关系。

于 2013-02-27T08:22:29.313 回答