2013-02-26 60 views
1

我有一個這樣的層次結構:的std :: is_base_of()深度

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 
+1

g ++ 4.7.2表現如預期:http://ideone.com/8yrx6k – hmjd 2013-02-26 13:28:36

+1

Clang 4.0的行爲如預期。 – 2013-02-26 13:29:55

+5

請在下次提供可複製問題的代碼。只要編譯你的代碼,你會發現它的語法不正確。 – mfontanini 2013-02-26 13:32:59

回答

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

Base是一個基類的Derived(10),而不考慮cv修飾符或BaseDerived不是工會並命名同一類類型而不關於cv修飾符

Base類被定義爲如此(§10):

BD類的基類,如果它是D的直接基類或D的基類之一的直接基類。

所以,是的,I1是一個基類的I3std::is_base_of<I1, I3>::value應該true

2

No, the code works:

#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以上的作品。如果你正在使用其他東西,你需要指定。

您的錯誤必須在別處。

0

我找到了問題。 我有一些單元測試的.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>(); 

應該/可能會失敗。但是,如果我讓班級名稱獨特,那就好了。

+0

這個代碼是無效的,它違反了_ONE定義Rule_,類名**必須在整個程序中是唯一的 – 2013-02-27 13:11:57

+0

是的。但MSVS10編譯它。 – deeptowncitizen 2013-02-27 14:50:31

+0

它不能編譯它,錯誤發生在單獨編譯的不同文件中,這就是C++的工作原理。 「我的代碼編譯」不同於「我的代碼是正確的」,這也是C++的工作原理。 ODR說你的程序有[tag:undefined-behaviour],那**不**表示它應該編譯失敗。 – 2013-02-27 15:29:18