繁体   English   中英

如何返回可变数量的各种类型的容器?

[英]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函数,将列名发送给该函数(例如,我可能需要tokenrank列),该函数会将指定列中的数据放入适当类型的容器中。

我的问题不是解析文件,而是返回可变数量的包含不同类型的容器。 例如,我希望将tokenrank列分别放入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如何转换每一列。

我至少可以想到两种解决方法:

  1. 使用可读取任何容器的模板化函数分别读取每一列( container::value_type允许该函数知道如何解析)。 我不喜欢这种解决方案,因为文件偶尔会很大(几百万行),因此多次解析它们会花费额外的几分钟(在计算时间约为30分钟的程序中,运行时的百分比不会忽略不计;该程序会一遍又一遍)。
  2. 将所有列读入字符串容器,然后在调用上下文中而不是在解析上下文中重新广播它们。 这不会太糟,因为我认为我可以使用std::transformboost::lexical_cast或s / t在一行中进行std::transform 如果我可以避免2n行膨胀,那就太好了( n =列数,通常为2或3,每列2行以声明容器,然后进行转换)。

与完整的通用解决方案相比,第二种解决方法可能需要我花费更少的精力; 如果是这样,我想知道。 我想第二种解决方法甚至可能更有效,但是我目前主要关注的是易用性。 如果我可以编写一个通用的readCols函数并完成它,那就是我的首选。

当事情变得太复杂时,我将问题分解为较小的部分。 所以这是一个建议。

编写一个CSV阅读器类,该类可以从文件中读取逗号或其他定界符分隔的值。 该类一次读取一行,并将该行分为std :: string字段。 为了访问这些字段,您需要实现诸如getString,getInt,getDouble之类的函数,这些函数可以访问字段(按列名或索引)并将其转换为适当的类型。 因此,读者可以做一个定义明确的事情,并处理数量有限的原始类型。

然后实施利用您的CSV阅读器的阅读器功能(或类)。 这些读取器函数知道列的特定类型以及将其值放置在标量,容器等中的位置。

只要返回值的类型受到限制,例如intdoublestd::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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM