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() はうまく機能しません-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
4

3 に答える 3

4

This does output true with 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;
}

Note that std::is_base_of<I1, I3>::value is equivalent to instantiating an object of type std::is_base_of<I1, I3> and converting it to bool.

I believe it is accurate in doing so. std::is_base_of<Base, Derived> is defined as having the condition (§20.9.6):

Base is a base class of Derived (10) without regard to cv-qualifiers or Base and Derived are not unions and name the same class type without regard to cv-qualifiers

Base class is defined as so (§10):

A class B is a base class of a class D if it is a direct base class of D or a direct base class of one of D's base classes.

So yes, I1 is a base class of I3 and std::is_base_of<I1, I3>::value should be true.

于 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 に答える