2012-02-24 5 views
0

ниже код не компилируетсяC++ не сопзИте на константном литья ошибки компиляции

void aaa(const int **a) { 
} 

int *a[] = {new int[2]}; 
aaa(a); 

я «не может преобразовать параметр 1 из„Int [1]“до«сопзЬ междунара *»в VS2010 и Подобная ошибка в НКУ

, когда я изменить свою декларацию:

int const *a[] = {new int[2]}; 

или

const int *a[] = {new int[2]}; 

компилирует, но я не понимаю, почему он не принимает ноны константного объявления переменного

ответ

8

Тип a: int*[]; тип, который вы хотите, - int const**. int*[] конвертирует в int**, но это не будет конвертировать неявно в int const**. Рассмотрим следующий код, чтобы понять, почему:

static int const ci = 42; 

void aaa(int const** out) 
{ 
    *out = &ci; 
} 

int 
main() 
{ 
    int* pa; 
    aaa(&pa);  // NOT LEGAL, because... 
    *pa = 0;  // would now change ci 
    std::cout << ci << std::endl; 
    return 0; 
} 

Как вы можете видеть, что позволяет это преобразование сломается сопзЬ без , требующих приведения.

В зависимости от того, что вы делаете, вы можете использовать:

void aaa(int const* const* out); 

неявное преобразование int** в int const *const * является законным. (В противном случае, вы будете нуждаться в const_cast где-нибудь, чтобы сообщить компилятору , что вы знаете, что вы делаете, и что это на самом деле не проблема.)

+0

возможно 'ааа (& годовых)' должен быть ' aaa (pa) ' – bitstore

+0

@tinybit или его объявление должно быть' int * pa; ', а использование после вызова должно быть' * pa = 0; '. Я отредактирую, чтобы исправить код в моем ответе. Спасибо, что заметили это. –

2

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

как int const *a[], так и const int *a[] на самом деле то же самое, что соответствует подписи aaa. Если вы попробовали int * const a[], это был бы другой тип (указатель-константа-указатель-на-int), и вы снова вызывали ошибку типа.

Если вы хотите, чтобы ваша функция aaa взять постоянный-указатель на указатель на междунар, вам нужно написать aaa(int ** const a), но имея константный-Несс на значения параметров не имеет фактически никакого влияния на то, что вы можете позвонить с ,


Edit:«Но не константность добавил неявно - сделано с неявной броском (который является собственно вопрос)?»

константность может быть неявно добавляется к значению вы прохождение, например

void aaa(const int a) {} 

int b=5; 
aaa(b); 

... или один указатель уровня

void aaa(const int* a) {} 

int *b=new int; 
aaa(b); 

... но не могут быть добавлены глубже. Например, это недопустимо:

void aaa(const int** a) {} 

int* b=new int; 
int** c=&b; 
aaa(c); 

Я думаю, что Джеймс Канзе объясняет это гораздо лучше в своем ответе.