[英]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.