Как сделать статическое утверждение, что приведение указателя тривиально?

Допустим, у меня есть следующие типы:

struct A {
    int a;
};

struct B {
    int b;
};

struct C : public A, public B {
    int c;
};

A C * указатель может быть преобразован в A * указатель вообще без изменения фактического адреса. Но когда C * приводится к B * , значение должно измениться. Я хотел бы убедиться, что два связанных типа, которые у меня есть, могут быть преобразованы друг в друга без изменения адреса (т.е. что нет множественного наследования или что базовый класс является первой базой производного класса). Это можно проверить во время выполнения, например, так

assert(size_t(static_cast((C*)0xF000) == 0xF000);
assert(size_t(static_cast((C*)0xF000) != 0xF000);

Это работает. Но эта информация известна во время компиляции, поэтому я ищу способ сделать для нее утверждение во время компиляции. Очевидные способы преобразования вышеуказанного в статическое утверждение (например, заменить assert на BOOST_STATIC_ASSERT дать ошибку «приведение к типу, отличному от целочисленного или перечисляемого типа не может появиться в константе-выражении» с g ++ 4.2.

Переносимость не т слишком важно. Использование расширений gcc или хитрых уловок с шаблонами вполне подойдет.

Обновление: Обнаружено, что почти тот же вопрос задавался раньше: C ++, статически определять базовые классы с разными адресами? . Использование offsetof () также является единственным полезным предложением.

7
задан Community 23 May 2017 в 09:58
поделиться