已经存在的遗留的 C 风格 API 接受的是数组和 char* 指针,这样的 API 函数还将会存在很长时间,如果我们要有效使用 STL 的话,就必须和它们和平共处。
如果有一个 vector 对象 v,而你需要一个指向 v 中数据的指针,以使得它可以被当作一个数组,只要 &v[0] 就可以了。对于 string 对象 s,相应的使用 s.c_str()
1 void doSomething( const int* pInts, size_t numInts ); 2 doSomething( &v[0], v.size() );
3 void doSomething( const char* pString ); 4 doSomething( s.c_str() );
对于 vector 使用不要使用 v.begin() 代替 &v[0],v.begin() 是迭代器,不是指针,一定要使用的话,键入&*v.begin()
string 的成员函数 c_str() 返回一个按 C 风格设计的指针,指向 string 的值
两种形式下,指针都被传递为指向 const 的指针
1 void doSomething( const int* pInts, size_t numInts ); 2 void doSomething( const cahr* pString );
vector 和 string 只能传给只读取而不修改它的API,对于 string 来说是唯一可做的,对于 vector 相对灵活一点。
如果想用 C 风格API返回的元素初始化一个 vector,可以利用 vector 和数组潜在的内存分配兼容性将存储 vector 的元素空间传给API函数:
1 // C API:此函数需要一个指向数组的指针,数组最多有 arraySize 个 double 2 // 而且会对数组写入数据。它返回写入的 double 数,不会大于 arraySize
3 size_t fillArray( double* pArray, size_t arraySize ); 4 vector<double> vd( maxNumDoubles ); // 建立一个 vector,大小是 maxNumDoubles 5 vd.resize( fillArray( &vd[0], vd.size() ) ); // 写入vd,然后调整 vd 的大小为fillArray
这个技巧只能工作于vector,因为只有vector承诺了与数组具有相同的潜在内存分布。
如果想用C风格 API 初始化 string 对象,只要让 API 将数据放入一个 vector<char>,然后再从 vector 中将数据拷到 string:
1 // C API:此函数需要一个指向数组的指针,数组最多有 arraySize 个 char 2 // 而且会对数组写入数据。它返回写入的 char 数,不会大于 arraySize 3 size_t fillString( char* pArray, size_t arraySize ); 4 vector<char> vc( maxNumChars ); // 建立一个 vector 5 size_t charsWritten = fillString( &vc[0], vc.size() );// 让 fillString 把数据写入 vc 6 string s( vc.begin(), vc.end() + charsWritten ); // 从 vc 通过范围构造函数拷贝数据到s
事实上,让 C 风格 API 把数据放入一个 vector,然后拷到你实际想要的 STL 容器中总是有效的:
1 size_t fillString( double* pArray, size_t arraySize ); 2 vector<double> vd( maxNumDoubles ); 3 vd.resize( fillArray( &vd[0], vd.size() ) ); 4 5 deque<double> d( vd.begin(), vd.end() ); // 拷贝数据到 deque 6 list<double> d( vd.begin(), vd.end() ); // 拷贝数据到 list 7 set<double> d( vd.begin(), vd.end() ); // 拷贝数据到 set
此外,对于 vector 和 string 以外的 STL 容器如何将他们的数据传给 C 风格 API。只要将容器的每个数据拷到 vector,然后将它们传给API:
void doSomething( const int* pints, size_t numInts ); set<int> intSet; . . . vector<int> v( intSet.begin(), intSet.end() ); // 拷贝 set 数据到 vector if( !v.empty() ) doSomething( &v[0], v.size() ); // 传递数据到 API
Effective_STL 学习笔记(十六) 如何将 vector 和 string 的数据传给遗留的API
原文:https://www.cnblogs.com/kidycharon/p/10009981.html