2017-01-11 67 views
1

我們正在使用stl容器遷移到現代C++。但具有類風格的舊c仍然存在。重構最難的領域之一是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:// EN。 cppreference.com/w/cpp/container/vector/data)而不是'&myFooTypes.front()'。 –

+2

「我不想創建不必要的突變或副本」 - 如果C函數期望終止數組,那麼您必須複製原始向量(或至少其內容),或通過追加終止符來變異向量。沒有其他的選擇。您可以想象在通話期間添加終止符,然後再將其刪除。 –

回答

-1

更好的解決方案是改變find_best_footype的接口來取指針和長度,而不是假設終止符。 (如果你要保持find_best_footype C兼容性)

然後,你可以寫:

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

,並沒有改變的載體。但是,這需要在別處進行更改。

+0

編號。如果我能改變API,我會的。但這不在我的控制之下。 –