2012-11-25 47 views
0
#include <cassert> 

struct a 
{ 
    virtual ~a() {} 
    char a_[10]; 
}; 

struct b 
{ 
    virtual ~b() {} 
    char b_[20]; 
}; 

struct c : public a 
{ 
    virtual ~c() {} 
    char c_[15]; 
}; 

struct d : public b, a 
{ 
    virtual ~d() {} 
    char d_[5]; 
}; 

int main() 
{ 
    a a_; 
    c c_; 
    d d_; 

    a* a__ = &a_; 
    a* c__ = &c_; 
    a* d__ = &d_; 

    assert((void*)&a_ == (void*)a__); 
    assert((void*)&c_ == (void*)c__); 
    assert((void*)&d_ == (void*)d__); // error on most compiler 
} 

我正在尋找一種方法來測試void * cast安全性之間的類繼承圖,它可以檢測編譯時的第三個斷言。編譯時間測試void *鑄造安全性在兩個類之間

template<typename Base, typename Derived> 
struct test 
{ 
    enum { 
     is_safe = (static_cast<Derived*>(static_cast<Base*>(nullptr)) == nullptr) 
    }; 
}; 

我的意圖是在上面的代碼中描述的,但它不會被編譯,因爲cast不是常量表達式。是否有可能以獨立於平臺/編譯器的方式進行檢查?

+0

輸入特徵來拯救。看到這裏:http://stackoverflow.com/questions/2631585/c-how-to-require-that-one-template-type-is-derived-from-the-other – SomeWittyUsername

+0

icepack // std :: is_base_of不是足夠。 is_base_of :: value和is_base_of :: value爲true,而只有第三個斷言(與a,d相關)在大多數編譯器上失敗。 – summerlight

回答

1

根據標準,從鑄造到Xvoid*然後從void*Y如果X僅明確定義相同Y。其他一切都是未定義的行爲。因此test唯一可能的便攜式,符合標準的定義是這樣的:

template<typename Base, typename Derived> 
struct test 
{ 
    enum { 
     is_safe = false; 
    }; 
}; 

template <typename X> 
struct test<X, X> 
{ 
    enum { 
     is_safe = true; 
    }; 
};