TAG

首都機能移轉 (2) 歌詞 (2) 靠北文 (40) 戲言 (30) 糟糕 (7) ACG (23) Assembly (2) Boost (2) C (31) C++ (69) CMake (4) CSIE (67) Debian (34) Design_Pattern (2) Django (1) Eclipse (1) en_US (13) FFmpeg (3) FoolproofProject (26) FreeBSD (2) Git (4) GNU_Linux (65) IDE (5) Java (11) JavaScript (19) KDE (15) Khopper (16) KomiX (3) Kubuntu (18) Life (1) Lighttpd (2) Mac_OS_X (2) Opera (1) PHP (2) PicKing (2) Programing (21) Prolog (1) Python (7) QSnapshot (2) Qt (30) Qt_Jambi (1) Regular_Expression (1) Shell_Script (7) Talk (98) VirtualBox (7) Visual_Studio (13) Windows (18) zh_TW (36)

2008年7月18日 星期五

Pass C++ vector as a C-sytle array

通常C的陣列都會要求像是int *之類的prototype,如果從C++的std::vector<int>要傳給那樣的函式,要怎麼辦呢?
由於std::vector保證元素的記憶體區塊是連續的,因此你可以用:
  1. &(*v.begin())
  2. &v[0]
  3. &(v.front())
來拿到陣列第一個位置,而對C來說也可以正確存取。
不過這不代表你可以用這種方式來取代原本的operator [],因為你會失去安全性。
為什麼不直接用v.begin()?因為它回傳的是iterator,std::vector<T>的實作並不保證它的iterator一定等效於T*,它只保證iterator一定可以Random Access,而T*只是其中一種實作法。
我個人會比較喜歡&v[0],因為還滿直覺,也符合C的風格。
其實我以前就知道std::vector是連續儲存,可是直到別人講起之前我都沒想到可以這樣做= =
果然知道和理解是有差異的。

7 則留言:

  1. 趕快換 Java 吧
    所有東西都幫你寫好了
    只是東西多到都不知道怎麼用 XDDD

    回覆刪除
  2. 不過所有我碰過的物件導向程式語言裡
    最討厭的就是Java....囧
    有空再來寫一篇我的偏見XD

    回覆刪除
  3. > 3. &(*v.front())

    v.front() 傳回的是 reference, 不是 iterator. 如果 T 沒有 operator* 或 T 不是 pointer type, *v.front() 將導致 compile error. 我猜這只是你的一時糊塗. :P

    > 不過這不代表你可以用這種方式來取代原本的operator [],因為你會失去安全性。

    沒看懂這句.

    ps. 我也對 Java 有偏見...

    回覆刪除
  4. 感謝,己更正!

    其實我的意思是
    避免去操作指向內部的指標
    比方說vector::at就會在out of range時throw一個異常出來(我知道有些大老討厭exceptions)
    而operator []....它也可能有某些封裝起來的行為,或是跟vector::at一樣會拋出異常
    恣意操作這些指標很容易出事
    而這不是這個手法的本意

    回覆刪除
  5. vector 的 operator[] 可說是 unchecked 版本的 vector::at, 也就是說沒有 out of bound error detection.

    除非是類似 VC 的 debug iterator 等的非標準 debug facility.

    回覆刪除
  6. 呃,好吧,從另一個角度來看好了
    在vector上實行array取值
    代表你要先拿到一個指標:
    std::vector<int> v;
    int * ip = &v[0];
    先不考慮v在施行resize或reserve之後其空間基點會不會改變(會的話ip就跟iterator一樣腐敗發臭了)
    甚至可以很愉快地施行
    delete [] ip;

    其實如果vector跟string一樣有提供data()就好了....

    回覆刪除