結構體的拷貝構造函數中,數組可以拷貝。

lambda的拷貝捕獲可以捕獲數組:int a[2]; [a] {}

structured binding也可以產生數組的拷貝:int a[2]; auto [x,y] = a;中,x和y綁定到a的副本中的元素。

甚至char a[] = "asdf";這種初始化也可以看作數組拷貝的特例。

所以拷貝數組似乎沒有技術上的難度。

數組不能直接拷貝,大概只能歸結於歷史原因。

很久很久以前,在C語言還不叫C語言的時候,數組名就是指針(不是const指針),那時對數組名的賦值就是指針賦值。後來為了支持結構體中的數組(思考一下,如果數組名就是指針,那麼結構體成員數組存儲在哪?),才做了區分,並禁止賦值。然而這裡留了個尾巴,作為函數形參的數組還是會轉換成指針。C++把這些規定都繼承過來了。

從此以後就一直沒允許直接拷貝。

這個尾巴還有點麻煩。考慮

int a[2];
int f(int b[2]);

這時f(a)會把a轉換成指針傳遞(而不是拷貝數組內容)。

類似地,auto b = a;也會把b當成指針(原因是auto的類型推導採用函數參數的規則)。

於是用int b[2] = a;形式進行數組內容拷貝還是受到很大阻力,到現在都沒法允許。


我認為這個設計不值得 defend, 只是一個增加了語言複雜程度的 cruft. 目前有一篇 paper 提議取消圍繞 builtin array 的這些特例, http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2020/p1997r1.pdf 使數組也能被賦值,用另一個數組初始化,和從函數中返回。


這是C語言的遺留問題,C裡面不能這麼寫所以C++一直也就沒做,再後來有了vector和array就更沒動力了。


有個東西叫memcpy啊


「為什麼c++中數組不能直接拷貝給另一數組?」

不是不能,是需要用不同的語法表達而已。

看你怎麼定義「直接拷貝」。難道說套了個循環,就叫「不直接」了?

實際上,其它那些抽象程度更高的語言,表面上讓你「直接」拷貝了數組,背地裡它可能是完全無腦給你新分配了一塊內存,因為它要保證內存不越界。而且複製過程中可能還會無意義地調用了默認構造器,再調用複製構造器。不信你可以試試看,支持「直接拷貝」的那些語言拷貝數組快,還是C++快。從這個角度來說,C++纔算真正的「直接拷貝」。

另外,C++也有抽象語法啊。就像其他大佬給你推薦的各種stl容器,也能一句話複製啊。

其實就是循環放哪裡的問題,該做的事情不可能變少(但是為了語法糖,反而可能會變多)。

不知道我該不該說一句?初學語言的同學,能不能不要只是對比「這個語法糖比那個語法糖更甜」,多想想語言實現背後的權衡、取捨,可能讓你提高還快點吧?


這跟異常有什麼關係?數組是c語言的產物,c語言有異常嗎?

在c語言裡面數組就是語法糖來的,一個語法糖誰考慮那麼多。而c++他爹一開始為了省事,直接沿用c語言設定,就是這麼回事。


用等號拷貝?

int a[4], b[4];

a = b;

你敢把一個常指針賦給另一個常指針???


建議用std::array


推薦閱讀:
相關文章