编译时间测试void *两类之间的铸造安全性

时间:2012-11-25 13:32:13

标签: c++ casting void-pointers

#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安全性的方法,它可以在编译时检测第三个断言。

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

我的意图在上面的代码中描述,但它不会被编译,因为强制转换不是常量表达式。是否可以以平台/编译器独立的方式检查它?

1 个答案:

答案 0 :(得分:1)

根据标准,如果Xvoid*相同,那么从void*Y以及从XY的投射只能定义明确test。其他一切都是未定义的行为。因此template<typename Base, typename Derived> struct test { enum { is_safe = false; }; }; template <typename X> struct test<X, X> { enum { is_safe = true; }; }; 唯一可能的,符合标准的可移植定义是:

{{1}}