Почему я получаю сообщение об ошибке преобразования "float **" в "const float **"? - PullRequest
29 голосов
/ 17 марта 2010

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

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

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

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

Ответы [ 4 ]

22 голосов
/ 17 марта 2010

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

(стр. 61)

[Примечание: если программа может назначить указатель типа T ** на указатель тип 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
}

- Конечная заметка]

21 голосов
/ 17 марта 2010

См. Почему я получаю ошибку при преобразовании Foo ** → const Foo **?

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

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

11 голосов
/ 08 марта 2013

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

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

Правильный способ достижения желаемого - изменить тип параметра функции на const float * const *.

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

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

8 голосов
/ 17 марта 2010

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

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

Подробнее см. C ++ FAQ Lite .

...