Итак, у меня есть этот код:
class ConstTest {
public:
explicit ConstTest(char* name) {}
};
int main() {
ConstTest t("blarghgh");
}
Это очевидно компилирует, хотя я думал, что это не должно Так как строковые литералы в C ++ имеют тип const char[]
, а также ConstTest
конструктор требует постоянных char*
— нет const char*
, И кастинг const
указатель на неконстантный тип обычно не делается C ++ неявно.
Так где я не прав? Почему он компилируется? Могу ли я юридически изменить разыменованный указатель внутри конструктора ?!
Так где я не прав? Почему он компилируется?
Он компилируется, потому что ваш компилятор слишком разрешительный, а ваш компилятор слишком разрешительный, потому что в C ++ 03 неявное преобразование строкового литерала в char*
был только осуждается, не является недействительным
Обоснованием была обратная совместимость с устаревшими API C. В соответствии с пунктом 4.2 / 2 стандарта C ++ 03:
Строковый литерал (2.13.4), который не является широким строковым литералом, может быть преобразован в значение типа «указатель на
char
«; широкий строковый литерал может быть преобразован в значение типа «указатель наwchar_t
». В любом случае,
Результатом является указатель на первый элемент массива. Это преобразование считается только при наличии
явный соответствующий целевой тип указателя, а не тогда, когда есть общая необходимость преобразования из lvalue в
Rvalue. [Заметка: это преобразование устарело. См. Приложение D.]
Однако в C ++ 11 неявное преобразование является недопустимым (приведенный выше абзац был полностью удален).
Можно ли юридически разыскивать и изменять указатель внутри конструктора ?!
Вы можете, но не можете изменить разыменованный объект. Это будет неопределенным поведением, так как тип объекта const
-qualified.
Других решений пока нет …