decltype квалифицированного идентификатора, обозначающего члена класса с `const T` против` T` в спецификаторе вложенного имени - PullRequest
7 голосов
/ 03 мая 2020

Должно ли быть подтверждено утверждение c в приведенном ниже коде?

#include <type_traits>
using namespace std;

struct S { int i; };
using CS = const S;

static_assert(is_same_v<decltype((CS::i)), decltype((S::i))>);

Clang и MSV C хорошо с этим, G CC считает, что утверждение срабатывает, потому что обозначенный тип decltype((CS::i)) - const int&, а тип, обозначенный decltype((S::i)) - int&: https://godbolt.org/z/5MqPX_. ( UPD: , как указано в комментариях, static_assert(is_same_v<decltype(CS::i), decltype(S::i)>); принимается всеми тремя компиляторами https://godbolt.org/z/V5y-tD, но меня интересует формулировка, которая гарантирует это).

[basi c .type.qualifier] / 1, кажется, только гарантирует, что T и const T имеют одинаковое представление и выравнивание объектов, но не то, что члены const T имеют одинаковое cv -квалификация в качестве соответствующих членов T.

Черт, если режим go 100% pedanti c: я даже не думаю, что Стандарт требует, чтобы поиск в const T нашел члена с именем N, если T имеет такой член. const T может использовать c_N вместо N и имеет те же требования к представлению объекта и выравниванию, что и T (при условии, что c_N имеет тип const decltype(T::N)). Я не нахожу слово «версия» в [basi c .type.qualifier] / 1, чтобы иметь какое-либо нормативное значение / обязательство.

INB4 вы указываете мне на C ++ 11 / C ++ 14 / C ++ 17's [class.name] / 5, говорящее

Если typedef-name , который называет cv-квалифицированный тип класса, используется, где class -name требуется, квалификаторы cv игнорируются.

спецификатор вложенного имени не требует имя-класса ( грамматика допускает как имя-класса , так и имя-типа-определения ). [class.derived] base-clause (→ base-specier-list base-спецификатор class-or-decltype ) делает (грамматика не позволяет typedef-name ). В любом случае, приведенное выше предложение было удалено в C ++ 20 P1131R2 , и формулировка о игнорировании cv-квалификаторов была помещена в [class.derived], единственное место, где оно применяется (в списке базовых классы в определении класса).

...