Я понимаю, что указатель, более квалифицированный CV на любом уровне, может указывать на менее квалифицированный CV объект на любом уровне
Это не совсем так, по крайней мерене так, как вы описали.Только самый верхний CV-квалификатор может быть добавлен произвольно (и, конечно, CV-квалификатор на самом указателе!), Как в случае C и C ++.
Вот контрпример дляПонятие «любой уровень», взятое прямо из [conv.qual/3]
в текущем проекте стандарта:
[Примечание: Если программа может назначить указатель типа T**
науказатель типа const T**
(то есть, если разрешена строка # 1 ниже), программа может непреднамеренно изменить объект const
(как это делается в строке # 2).Например,
int main() {
const char c = 'c';
char* pc;
const char** pcc = &pc; // #1: not allowed
*pcc = &c;
*pc = 'C'; // #2: modifies a const object
}
- конечная нота]
В любом случае, тогда вы спрашиваете:
но почему нет?То же самое для структур?
Конечно, вы можете указать const T*
на T
, но это не то, что вы делаете.Это правило не применяется рекурсивно.Классы могут содержать более одного члена, поэтому ваш подход просто не работает в целом (и нет необходимости в специальном правиле для классов, состоящих из одного члена).
В этом конкретном случае два класса являются макетамисовместим, поэтому я ожидаю, что reinterpret_cast
будет работать в большинстве случаев:
struct s_t {
int a;
};
struct c_s_t {
const int a;
};
int main()
{
s_t s;
c_s_t *c_s = reinterpret_cast<c_s_t*>(&s);
}
Однако, похоже, что алиасы по достоинствам совместимости с макетом на самом деле не определены четко , так что в конечном итоге вам лучше переосмыслить свой дизайн.
tl; dr: Различные типы - это разные типы.