Тестирование времени компиляции void * приведение безопасности между двумя классами

#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 * в графе наследования классов, который может обнаружить третье утверждение во время компиляции.

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

Мое намерение описано в приведенном выше коде, но оно не будет скомпилировано, потому что приведение не является константным выражением. Можно ли проверить это независимо от платформы / компилятора?

0

Решение

Согласно стандарту, отливка из X в void* а затем из 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;
};
};
1

Другие решения

Других решений пока нет …

По вопросам рекламы [email protected]