[英]How can I return a variable number of containers of various types?
我有看起來像這樣的數據:
token eps rank # first line names columns
Intercept 9.362637e+00 1 # later lines hold data
A1 -2.395553e-01 30
G1 -3.864725e-01 50
T1 1.565497e-01 43
....
不同的文件將具有不同數量的命名列,並且每一列中值的類型將在浮點數,整數和字符串之間變化。
我想編寫一個readCols
函數,將列名發送給該函數(例如,我可能需要token
和rank
列),該函數會將指定列中的數據放入適當類型的容器中。
我的問題不是解析文件,而是返回可變數量的包含不同類型的容器。 例如,我希望將token
和rank
列分別放入vector<string>
和vector<int>
容器中。 這里的問題是我可能希望改為使用eps
列(存儲在向量中),並且我不想為每種可能的類型組合編寫不同的readCols
函數。 (容器的類型對我來說無關緊要。如果我只需要使用vector
,就沒問題;每個容器包含不同的類型是關鍵。)
我可能需要一個容納不同類型容器的容器,以容納不同類型的容器。 看起來Boost.Variant可能是我想要的解決方案,但我不知道如何告訴解析器我希望每一列為哪種類型(我可以像類型名列表那樣進行操作嗎?例如void readCols(string filename, vector<variant<various types of vector>> &data, vector<string> colNames, vector<typename> convertTo)
)。 同樣, Boost.Mpl.Vector可能解決了這個問題,但是我還是不太清楚如何告訴readCols
如何轉換每一列。
我至少可以想到兩種解決方法:
container::value_type
允許該函數知道如何解析)。 我不喜歡這種解決方案,因為文件偶爾會很大(幾百萬行),因此多次解析它們會花費額外的幾分鍾(在計算時間約為30分鍾的程序中,運行時的百分比不會忽略不計;該程序會一遍又一遍)。 std::transform
和boost::lexical_cast
或s / t在一行中進行std::transform
。 如果我可以避免2n
行膨脹,那就太好了( n
=列數,通常為2或3,每列2行以聲明容器,然后進行轉換)。 與完整的通用解決方案相比,第二種解決方法可能需要我花費更少的精力; 如果是這樣,我想知道。 我想第二種解決方法甚至可能更有效,但是我目前主要關注的是易用性。 如果我可以編寫一個通用的readCols
函數並完成它,那就是我的首選。
當事情變得太復雜時,我將問題分解為較小的部分。 所以這是一個建議。
編寫一個CSV閱讀器類,該類可以從文件中讀取逗號或其他定界符分隔的值。 該類一次讀取一行,並將該行分為std :: string字段。 為了訪問這些字段,您需要實現諸如getString,getInt,getDouble之類的函數,這些函數可以訪問字段(按列名或索引)並將其轉換為適當的類型。 因此,讀者可以做一個定義明確的事情,並處理數量有限的原始類型。
然后實施利用您的CSV閱讀器的閱讀器功能(或類)。 這些讀取器函數知道列的特定類型以及將其值放置在標量,容器等中的位置。
只要返回值的類型受到限制,例如int
, double
或std::string
,這樣的函數就可以完成工作:
using namespace std;
void readCols(string fileName, vector<string> stringCols,
vector<string> intCols, vector<string> doubleCols,
vector<vector<string> > *stringData,
vector<vector<int> > *intData,
vector<vector<double> > *doubleData);
(可能足夠清晰,但是您可以根據列類型列出所需的列名。)
旁觀者認為這是比變通辦法更多或更小的麻煩。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.