Ошибка gcc: недопустимое преобразование из double * в const double - PullRequest
4 голосов
/ 25 октября 2011

Я использую gcc версии 4.5.0. Используя следующий простой пример, я предполагаю получить ошибку недопустимое преобразование из double * в const double *

#include <iostream>
using namespace std;

void foo(const double *a)
{
    cout<<a[0]*2.<<endl;
}

int main()
{
    double *a=new double[2];
    a[0]=1.;
    a[1]=2.;
    foo(a);
    return 1;
}

Почему он компилируется без ошибок?

Контрпримером является следующий аналог:

#include<iostream>
using namespace std;

void foo(const double **a)
{
cout<<a[0][0]*2.<<endl;
}


int main()
{
    double **a=new double*[2];
    a[0]=new double[2];
    a[1]=new double[2];
    a[0][0]=1.;
    foo(a);
    cout<<a[0][0]<<endl;
    return 1;
}

(Решение для второго примера: определить foo как foo (const double * const * a). Благодаря комментарию Джека Эдмондса это объясняет сообщение об ошибке)

Ответы [ 4 ]

8 голосов
/ 25 октября 2011

Как правило, вам разрешено неявно делать вещи «более постоянными», но не «менее постоянными» в C и C ++.Следовательно, вам разрешено передавать неконстантный объект в функцию, которая принимает константный объект.

По сути, параметр const в объявлении метода - это способ обещания не изменять параметр.

Вы можете увидеть этот вопрос для получения дополнительной информации: Вопрос о const_cast в c ++

6 голосов
/ 25 октября 2011

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

4 голосов
/ 25 октября 2011

Вы должны иметь возможность инициализировать тип данных const.Можно передать double* параметру const double*.Таким образом, вы можете делать то, что вам нужно, в вызывающем абоненте, но вызываемый не имеет права изменять то, что вы сказали const.

Когда вы идете другим путем, вы получаете ошибкии предупреждения.

0 голосов
/ 25 октября 2011

Преобразование double * в const double * в качестве типа параметра допустимо, так как у вас было много ответов, сообщающих вам об этом.

Однако есть странная ловушка, которую вы, возможно, видели раньше, которая не компилируется, что может стать причиной вашей путаницы сейчас. Если вы не видели подобного кода, который не компилируется, вы можете пропустить этот ответ, потому что он может сбить вас с толку больше, чем помочь. Я добавляю дополнительные подробности только в том случае, если вы думали, что раньше это не работало.

Иногда свойство const может быть нарушено при вставке константного типа обратно в CALLER через указатель параметра константного типа, который имеет меньшую константность в CALLER. Это приводит к ошибке компиляции, которая на первый взгляд выглядит как то же преобразование, что и вы. Например, если у вас есть функция void bar(const double **a) и вы вызываете ее с помощью foo(&a) в своей основной записи, вы получите ошибку компиляции, даже если кажется, что в другой ситуации вы только делаете тип более постоянным.

См. Этот вопрос для более подробной информации об этой ситуации.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...