对于 vector 来说, \(v[0]\) 的地址 \(\&v[0]\) 便可做为数组指针传递给 C API:java
1: // Legacy C API. 2: extern void doSomething(const int* pInts, size_t numInts); 3: 4: vector<int> v; 5: // ... 6: // Operations on v. 7: // ... 8: 9: if (!v.empty()) 10: { 11: doSomething(&v[0], v.size()); 12: }
也许有人会说:能够用 v.begin() 来替代 \(\&v[0]\), 但并不是永远如此, v.begin() 返回的是一个迭,迭代器指向的对象的地址才是真正的 \(\&v[0]\) ,即:c++
&*v.begin() == &v[0]
String 对象没有要求保证全部字符串都存放在连续的内存空间,并且 string 内部不会保证内存中对象会以 NULL 结尾,上面对 \(\&v[0]\) 的方法对 string 不必定行得通,对 string 来说,咱们应该使用它提供的成员函数: c_str() , 下面的代码中无需检查 ss 是否为空,由于若是 ss 为空, ss.c_str() 会返回 NULL 。sql
13: // Legacy C API: 14: extern void doSomething(const char* str); 15: 16: string ss; 17: // ... 18: // Do something with ss 19: // ... 20: 21: doSomething(ss.c_str());
注意第 2 和第 14 行中 C API 中的 const 限定符,调用的函数不该该修改指针指向的内容,但若是咱们须要经过调用 C API 来初始化 vector 或 string,应该怎么作?数组
对于 vector 来说, Item 14 提到,经过 reserve() 能够预留出足够的空间,并且是连续空间,这样咱们能够在调用 C API 进行初始化以前来分配好足够空间,并在初始化以后调用 resize() 来改变容器的大小:bash
// C API: this function takes a pointer to an array of at most arraySize // doubles and writes data to it. It returns the number of doubles written, // which is never more than maxNumDoubles. size_t fillArray(double *pArray, size_t arraySize); vector<double> vd; vd.reserve(maxNumDoubles); vd.resize(fillArray(&vd[0], maxNumDoubles))
或者更简单的:函数
vector<double> vd(maxNumDouble); vd.resize(fillArray(&vd[0], vd.size()));
String 提供的 c_str() 指向的指针是只读的,不能将其传给 C API 进行初始化,但咱们能够经过前面提到的方法:将 vector<char> 的指针传给 C API,而后再用这个 vector 来初始化 stringpost
// C API: this function takes a pointer to an array of at most arraySize // chars and writes data to it. It returns the number of chars written, // which is never more than maxNumChars. size_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 来初始化一个 set:this
size_t doSomething(int* pints, size_t numInts); // C API to initialize int array. vector<int> v(maxNumInts); // This is media size_t sz = doSomething(&v[0], v.size()); set<int> intSet(v.begin(), v.begin()+sz);