获取指针
</br>
假设有一个vector对象v,而你需要得到一个指向v中数据的指针,这让v可以被当作一个数组在C中使用。
我们只需要使用&v[0]
即可获得指向首元素的指针。如果是string,请使用s.c_str()
.
实际上这样做可能会有一些问题,具体而言就是v可能是空的,所以需要先对v进行empty判定。
有人说可以用begin这种迭代器来代替&v[0],实际上这完全是胡说八道,因为并不总是能做到迭代器和指针之间的互相转换。&*v.begin()
倒是真的可以等价于&v[0]
,但这种写法除了让别人一目了然你的智力水平外并没有其他好处。
有人会疑惑为什么vctor就可以直接取址,而string不行,原因有以下两点:
- string的数据并没有保证被存储于连续内存(详见 Effective STL 15)
- string并不保证以null结尾
因此,string必须使用c_str:
1
2
void doSomething(const char *pString);
void doSomething(s.c_str());
1 | void doSomething(const char *pString); |
C API初始化STL容器
用C API返回的元素初始化vector
1 | // C API数需要一个指向数组的指针,数组最多有arraySize个double |
用C API返回的元素初始化string
上述写法并不能应用于string类型,因为只有vector保证了与数组具有相同内存分布。(顺序表)
但用用C API初始化string也不难,具体来说就是先初始化一个vector<char>,然后再用vector初始化string:1
2
3
4size_t fillString(char *pArray, size_t arraySize);
vector<char> vc(maxNumChars);
size_t charsWritten = fillString(&vc[0], vc.size());
string s(vc.begin(), vc.begin()+charsWritten);
用C API返回的元素初始化STL中的任何容器
因为和数组内存分布一致的只有vector,所以我们的策略十分简单:把数组内的元素传入vector,然后再用vector初始化STL容器:1
2
3
4
5
6size_t fillArray(double *pArray, size_t arraySize);
vector<double> vd(maxNumDoubles);
vd.resize(fillArray(&vd[0], vd.size()));
deque<double> d(vd.begin(), vd.end()); // 拷贝数据到deque
list<double> l(vd.begin(), vd.end()); // 拷贝数据到list
set<double> s(vd.begin(), vd.end()); // 拷贝数据到set
STL容器传递数据至C API
</br>
从上文中自然能领会到反向传递的方法:用STL容器内的元素初始化vector,然后再用vector传入C API:1
2
3
4void doSomething(const int* pints, size_t numInts);
set<int> intSet; //要传递给API数据的set
vector<int> v(intSet.begin(), intSet.end());
if (!v.empty()) doSomething(&v[0], v.size());