Effective_STL 學習筆記(十六) 如何將 vector 和 string 的數據傳給遺留的API
已經存在的遺留的 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( constchar* 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( constcahr* 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