Почему я получаю ошибку при преобразовании "float**" в " const float**"?

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

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

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

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

4 ответов


посмотреть почему я получаю ошибку при преобразовании Foo * * → const Foo**?

потому что преобразование Foo**const Foo** будет недействительным и опасным ... Причина преобразования из Foo**const Foo** опасно то, что это позволит вам тихо и случайно изменить объект const Foo без приведения

ссылка далее дает пример того, как такое неявное преобразование может позволить мне изменить const объект без гипса.


это очень сложное ограничение. Это связано с правилами псевдонимов языка. Взгляните на то, что говорят стандарты, потому что я уже сталкивался с этим однажды:

(стр. 61)

[Примечание: если программа может назначить указатель типа T** к указателю введите const T** (то есть, если строка / / 1 ниже было разрешено), программа может ненароком изменить объект const (как это делается в line / / 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
}

-конец Примечание]


другие anwers подробно объяснили, почему это ошибка в C++.

позвольте мне обратиться к вопросу, стоящему за вашим вопросом. Вы хотели заявить в интерфейсе своей функции, что ваша функция не будет изменять значения float, содержащиеся в массиве. Хорошее намерение и позволяет вызывать вашу функцию с помощью const float ** массивы. Вопрос за вашим вопросом будет заключаться в том, как достичь этого, не разрешая уродливые слепки.

правильный путь достигнуть чего вы хотела изменить тип параметра функции const float * const *.

дополнительные const между звездами гарантирует компилятору, что ваш метод не будет пытаться хранить указатели на const float в массиве, так как этот тип объявляет, что значения указателей также const.

теперь вы можете вызвать эту функцию с помощью float ** (который был примером в вашем вопросе), const float ** и const float * const * аргументов.


если вы преобразовали параметр в const float** затем вы можете сохранить const float* в месте памяти, на которое указывает параметр. Но вызывающая функция думает, что это место памяти должно содержать неконст float* и может позже попытаться изменить это указывает на float.

поэтому вы не можете бросить float** до const float**, Это позволит вам хранить указатели на константы в местах, где ожидается указатели на изменяемые значения.

для более подробно см. C++ FAQ Lite.