Effective STL:vectorとstringのデータを歴史に残るCスタイルAPIに渡す

4425 ワード

vectorオブジェクトvがある場合、&v[0]を使用すれば、v内のデータを指すポインタを得る必要があります.stringオブジェクトsに対して、対応する呪文は簡単なs.c_です.str().
void doSomething(const int* pInts, size_t numInts);

if (!v.empty()) //   v  ,&v[0]                    
{
    doSomething(&v[0], v.size());
}

//    vector               , string     ,  // 1 string                       // 2 string              null    void doSomething(const char *pString);
doSomething(s.c_str()); //     s     

注意:vectorとstringのデータは、そのAPIを変更せずに読み取りのみに転送することが望ましい.vをその要素を変更するCスタイルのAPIに転送すると、典型的には問題ないが、呼び出された関数はvectorの要素の数を変更しようとしない.
CスタイルAPIで返される要素でSTLコンテナを初期化
CスタイルAPIで返される要素でvectorを初期化したい場合は、vectorと配列の潜在的なメモリ分散互換性を使用してvecotrを格納する要素の空間をAPI関数に渡すことができます.
// C API:              ,     arraySize double//           。      double ,    arraySize
size_t fillArray(double *pArray, size_t arraySize);

vector<double> vd(maxNumDoubles); //     vector,   maxNumDoubles
vd.resize(fillArray(&vd[0], vd.size())); //  fillArray     vd,    vd    fillArray       

このテクニックはvectorでしか動作しない.vectorだけが配列と同じ潜在的なメモリ分布を持つことを約束しているからだ.しかし、柔軟に発揮して、他のSTL容器でもいいです.
// C API:              ,     arraySize char//           。      char ,    arraySize
size_t fillString(char *pArray, size_t arraySize);

vector<char> vc(maxNumChars); //     vector,   maxNumChars
vd.resize(fillString(&vc[0], vc.size())); //  fillString     vc,    vd    fillArray       

string str(vc.begin(), vc.end()); //  vc             stringdeque<char> d(vd.begin(), vd.end()); //      dequelist<char> l(vd.begin(), vd.end()); //      listset<char> s(vd.begin(), vd.end()); //      set

vectorとstring以外のSTLコンテナはどのようにしてそれらのデータをCスタイルAPIに伝えますか?
コンテナの各データをvectorにコピーし、APIに渡す限り:
void doSomething(const int* pints, size_t numInts); // C APIset<int> intSet; //       API   set
...
vector<int> v(intSet.begin(), intSet.end()); //   set   vectorif (!v.empty())
{
    doSomething(&v[0], v.size()); //      API
}