標籤:stl vector string c api
通常情況下,舊的C API使用數組合char*指標來進行資料交換而不是vector或string對象。這樣的API還將存在很長的一段時間,如果我們想有效地使用STL,我們就必須與它們和平共處。
幸運的是,這很容易做到。如果有一個vector v,而需要得到一個指向v中資料的指標,從而可把v中的資料作為數組來對待,那麼只需要使用&v[0]就可以了。對於string s,對應的形式是s.c_str()。所以,如果我們希望把v傳給一個如下所示的C API:
void dosomething(const int* pInts,size_tnumInts);
則我們可以這樣做:
if (!v.empty())
{
dosomething(&v[0],v.size());
}
因為v可能是空的,&v[0]則試圖產生一個指標,而該指標指向的東西並不存在。這可不好,所以需要先判斷一下,確保安全。
上述得到容器中指標的方式對於vector是適用的,但對於string卻是不可靠的。因為(1)string中的資料不一定儲存在連續的記憶體中;(2)string的內部表示不一定是以Null 字元結尾的。這也正說明了為什麼在string中存在成員函數c_str()。c_str()函數返回一個指向字串的值的指標,而且該指標可用於C。因此,我們可以把一個字串s傳給下面的函數:
void dosomething(const char* pString);
如下所示:
void dosomething(s.c_str());
注意:如果傳遞的C API改變了v中元素值的話,通常是可以的,但被調用的常式不能試圖改變向量中元素的個數。比如,不能試圖在vector的未使用的容量中建立新元素。不然,v的內部將會變得不一致,因為它從此無法知道自己的正確的大小,v.size()將產生不正確的結果。
先讓C API把資料寫入到一個vector中,然後把資料拷貝到期望最終寫入的STL容器中,這一思想總是可行的:
size_t fillArray(double *pArray,size_t arraySize);
vector<double> vd(maxNumDouble);
vd.resize(fillArray(&vd[0],vd.size()));
deque<double> d(vd.begin(),vd.end());
list<double> l(vd.begin(),vd.end());
set<double> s(vd.begin(),vd.end());
而且這意味著,除了vector和string以外的其他STL容器也能把他們的資料傳遞給C API。只需要把每個容器的元素拷貝到一個vector中,然後傳給該API:
void dosomething(const int* pInts,size_tnumInts);
set<int> intSet;
…
vector<int>v(intSet.begin(),intSet.end());
if (!v.empty())
dosomething(&v[0],v.size());