Почему я получаю ошибку, конвертирующую 'float ** в' const float **?
У меня есть функция, которая принимает float**
в качестве аргумента, и я попытался изменить ее, чтобы взять const float**
.
Компилятор (g++
) не понравился и выдал:
invalid conversion from ‘float**’ to ‘const float**’
это не имеет для меня никакого смысла, я знаю (и проверял), что могу передать char*
функции, которая принимает const char*
, так почему бы не с const float**
?
Ответы
Ответ 1
См. Почему я получаю сообщение об ошибке преобразования Foo ** → const Foo **?
Поскольку преобразование Foo**
→ const Foo**
было бы недействительным и опасным... Причина, по которой преобразование из Foo**
→ const Foo**
является опасной, заключается в том, что она позволит вам тихо и случайно изменить объект const Foo без отливать
Далее приводится пример того, как такое неявное преобразование может позволить мне изменить объект const
без трансляции.
Ответ 2
Это очень сложное ограничение. Это связано с правилами псевдонимов языка. Посмотрите, что говорят стандарты, потому что я столкнулся с этим раньше:
(Страница 61)
[Примечание: если программа может назначить указатель типа T ** на указатель type 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
}
-end note]
Ответ 3
Другие анонсы подробно остановились на том, почему это ошибка в С++.
Позвольте мне затронуть вопрос, стоящий за вашим вопросом. Вы хотели бы указать в интерфейсе своей функции, что ваша функция не будет изменять значения float, содержащиеся в массиве. Хорошее намерение, и позволяет, что ваша функция вызывается с массивами const float **
. Вопрос, стоящий за вашим вопросом, состоял бы в том, как достичь этого, не решаясь к уродливым броскам.
Правильный способ достижения желаемого - изменить тип параметра функции на const float * const *
.
Дополнительный const
между звездами гарантирует компилятору, что ваш метод не попытается сохранить указатели на const float в массиве, так как этот тип объявляет, что значения указателя также являются константами.
Теперь вы можете вызвать эту функцию с помощью float **
(который был примером в вашем вопросе), const float **
и const float * const *
аргументов.
Ответ 4
Если вы преобразуете параметр в const float**
, вы можете сохранить const float*
в ячейке памяти, на которую указывает этот параметр. Но вызывающая функция считает, что это место памяти должно содержать неконстантный float*
и позже может попытаться изменить этот указатель на float
.
Поэтому вы не можете использовать float**
для const float**
, это позволит вам хранить указатели на константы в местах, где ожидаются указатели на изменяемые значения.
Подробнее см. С++ FAQ Lite.