2017-01-11 3 views
1

stlコンテナを使用して最新のC++に移行しています。しかし、クラススタイルの古いCが続く。リファクタリングの最も難しい領域の1つはC apiのインタフェースです。stlコンテナをC関数に渡すためのガイドライン

// foo_types_list (array terminated by FOO_TYPE_NONE) 
enum FooTypes find_best_footype(const enum FooTypes *foo_types_list, 
             unsigned int capabilities); 

std::vector<FooTypes> myFooTypes{ FOO_TYPE_A, FOO_TYPE_ZZ, FOO_TYPE_B }; 

FooTypes foo = find_best_footype(&myFooTypes.front(), 42); // fail, not terminated. 

これらのc-apiを収容するための最良の戦略は何ですか?私は呼び出しを行うためにベクトルを終了する必要がありますが、私は不要な変異やコピーを作成したくないですか?

コピーを作成する以外に方法がない場合、C関数のアクセサと互換性のあるデータ構造を作成する簡単な方法は何ですか?

+1

'のstd ::ベクトル myFooTypes {FOO_TYPE_A、FOO_TYPE_ZZ、FOO_TYPE_B、FOO_TYPE_NONE}'、または 'myFooTypes.push_back(FOO_TYPE_NONE)は' – user3528438

+2

は(HTTP [スタンダード::ベクトル::データ]を使用することを検討してください。 cppreference.com/w/cpp/container/vector/data)を '&myFooTypes.front()'の代わりに使用します。 –

+2

"不要な突然変異やコピーを作成したくありません" - C関数で終了配列が必要な場合は、元のベクター(または少なくともその内容)をコピーするか、ターミネーターを追加してベクターを突然変異させる必要があります。他の選択肢はありません。おそらくは、通話中にターミネータを追加してからもう一度削除することもできます。 –

答えて

-1

より良い解決策は、find_best_footypeのインターフェイスを、ターミネータを想定するのではなく、ポインタと長さを取るように変更することです。

FooTypes foo = find_best_footype(myFooTypes.data(), myFooTypes.size(), 42); 

をしてベクトルを変更する必要はありません。(あなたはfind_best_footypeのためのCとの互換性を維持する必要がある場合)

は、次に、あなたが書くことができます。ただし、これには他の場所で変更が必要になります。 // EN;

+0

NO。もし私がapiを変えることができたら、私はそうするでしょう。しかし、これは私のコントロール下にありません。 –

関連する問題