Подтвердить что ты не робот

Почему я получаю ошибку, конвертирующую 'float ** в' const float **?

У меня есть функция, которая принимает float** в качестве аргумента, и я попытался изменить ее, чтобы взять const float**.

Компилятор (g++) не понравился и выдал:

invalid conversion from ‘float**’ to ‘const float**’

это не имеет для меня никакого смысла, я знаю (и проверял), что могу передать char* функции, которая принимает const char*, так почему бы не с const float**?

4b9b3361

Ответ 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.