2013-08-29 33 views
3

爲什麼下面的代碼皺起了眉頭?是reinterpret_cast到C風格的數組非法C++ 11?

double d[4] = {0,1,2,3}; 
reinterpret_cast<double[2]>(d); 

GCC聲明它的invalid cast from type 'double*' to type 'double [2]'和鐺聲明reinterpret_cast from 'double *' to 'double [2]' is not allowed

現在的情況下,意圖不是很明顯,我想這個代碼返回一個double [2]包含{0,1},非常像reinterpret_cast<double*>(d)會。 (所以我知道它會使用指針工作,所以這不是我在問什麼)

+0

沒有表達式可以在C或C++中產生數組 - 數組不能爲右值。他們總是有一個名字和一個地址。 – JohannesD

+0

@JohannesD是一個字符串文字表達式? :P –

+0

@ R.MartinhoFernandes該死的,你讓我在那裏:P另外,在C99中有數組字面值......噢。也許正確的事情是,在運行時不能有*臨時*數組對象。字符串文字(大概是C99數組文字)仍然是左值,而不是右值。 – JohannesD

回答

4

兩種編譯器是正確的。

reinterpret_cast是不是一個錘子,這是一個功能強大的精密工具。的reinterpret_cast所有用途必須涉及至少一個指針或引用類型爲源或作爲目的地,除了一個身份積分變換的退化情況(即,從intintreinterpret_cast是允許的,什麼也不做。)

1

你有大小4的數組(不是指針),你不能把它轉換成2的數組簡單的,因爲事實上,大小是不正確的。一個類似的例子是,你不能將一個類的實例轉換爲另一個類的實例的類的實例,因爲這樣做沒有任何意義。要獲得與{0,1}陣列,你必須做一個全新的陣列。

這裏是做正確的方式:

 double d[4] = {0,1,2,3};              
    double copy[2]{};               
    std::copy_n(std::begin(d),2,std::begin(copy)); 

如果你不想創建數組的習慣做的事情是在一個範圍,而不是一個數組操作的副本,有一個因爲標準庫中的每個算法都在迭代器而不是容器上運行。

+0

嗯,我想要別名我的數組的子集。不要複製它是整個問題。 –

+3

@GurgHackpof這就是全部的原因,C++使用迭代器它的所有算法,在一個範圍內工作,不要試圖做任何事情棘手 – aaronman

6

你可能想要的是

double (&d2)[2] = reinterpret_cast<double(&)[2]>(d); 
+1

OK請賜教,什麼這個東西實際上意味着。 它似乎與GCC [(示例)](http://coliru.stacked-crooked.com/view?id=0de88e758516912c699e7c1993b30cbd-1dfe2a0b480865877d574c97e8ac73e5),但clang警告說,它是未定義的reinterpret-cast錯誤:reinterpret_cast從 '雙[4]' 到 '雙(&)[2]' 有未定義的行爲[-Werror,-Wundefined-重新解釋鑄]' –

+0

這是數組的引用。不好的是UB ... – Jarod42

+3

@GurgHackpof如果編譯器說這是一個可怕的想法,它可能是:) – aaronman

相關問題