#новичкам
Спасибо, @Ivaneo, за любезно предоставленный примерчик в рамках рубрики #ЧЗХ.
Дан простой кусочек кода:
const char* s1 = "First";
constexpr char* s2 = "Second";
constexpr const char* s3 = "Third";
static_assert(std::is_const_v<decltype(s1)>);
static_assert(std::is_const_v<decltype(s2)>);
static_assert(std::is_const_v<decltype(s3)>);
Все просто. Тип 3-х переменных проверяется на константность.
Вопрос: сможете сказать без компилятора какой из трех вариантов нормально соберется, какой выдаст assert, а какой выдаст warning?
Возьмите паузу на подумать.
Ответ будет такой:
static_assert(std::is_const_v<decltype(s1)>); // выдаст ассерт
static_assert(std::is_const_v<decltype(s2)>); // выдаст варнинг
static_assert(std::is_const_v<decltype(s3)>); // нормально скомилится
ЧЗХ? Там же все константное?
Здесь дело в особенностях константности указателей. Чуть подробнее мы это разбирали в этом посте, но сейчас краткая выжимка.
Бывают константные указатели и указатели на константы. И это разные типы! Первый нельзя передвигать, но можно изменять данные, на которые он указывает. Второй можно передвигать, но данные изменить не получится.
Так вот ассерты проверяют является ли сам указатель константным.
s1 - это неконстантный указатель на константу, поэтому срабатывает ассерт.Теперь с constexpr разбираемся. Этот спецификатор подразумевает const. И так как его нельзя применять более одного раза при объявлении переменной, то он применяется к самой "верхушке" типа. То есть
s2 и s3 становятся константными указателями. И для них ассерты не срабатывают.Для
s2 выдается варнинг, потому что мы пытаемся присвоить строковый литерал, который имеет тип const char[], то есть массив константных символов, к указателю на неконстанту. В нормальной ситуации это бы вызвало ошибку компиляции, но такие преобразования возможны в С. И С++ сохраняет здесь совместимость, хоть и стремается этого и генерирует предупреждение о такой опасной ситуации.Все примеры довольно просто объяснимы, хотя на первый взгляд лицо деформируется в вопросительный знак. Помните об особенностях константности указателей и будет вам счастье.
Be amazed. Stay cool.
#cppcore