2012-02-24 29 views
0

下面的代碼不編譯C++非常量爲const鑄造編譯錯誤

void aaa(const int **a) { 
} 

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

我 「不能從轉換參數1 'INT [1]' 至「const int的*」 在VS2010和在GCC類似的錯誤

當我改變我的聲明:

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

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

它編譯,但我不明白爲什麼它不接受非const的變量聲明

回答

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; 
} 

正如你看到的,讓這種轉換會破壞const沒有 需要演員。

取決於你在做什麼,你可能需要使用:

void aaa(int const* const* out); 

int**int const *const *的隱式轉換是合法的。 (否則,你需要一個const_cast的地方,告訴編譯器 ,你知道你在做什麼,這是不是一個真正的問題。)

+0

也許'AAA(PA)'應該是' aaa(pa)' – bitstore 2012-02-24 15:33:47

+0

@tinybit或者它的聲明應該是'int * pa;',調用後的使用應該是'* pa = 0;'。我將編輯修復我的答案中的代碼。感謝您發現這一點。 – 2012-02-24 16:44:36

2

功能aaa需要一個指針到指針到恆-INT。 您的變量a是一個指向int指針的指針。 將後者分配給前者是錯誤的。

int const *a[]const int *a[]實際上是相同的東西,匹配的簽名aaa。如果你試過int * const a[],那將是一個不同的類型(pointer-to-constant-pointer-to-int),你會再次觸發類型錯誤。

如果您希望函數aaa採用常量指針指向int的指針,則需要編寫aaa(int ** const a),但對參數值的常量實際上並不影響可調用的內容。


編輯:「但不是常量性暗示加 - 與隱式轉換完成(這是實際的問題)?」

常量性可以被默認添加到你的價值通過,例如

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); 

我認爲James Kanze在他的回答中解釋得更好。