如何返回可变数量的各种类型的容器
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
s,没问题;每个容器包含不同的类型是键。
我可能需要一个容纳不同类型的容器来容纳不同类型的容器。 看起来 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 进行转换。 如果我能避免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);
(可能足够清楚,但您可以根据它们的类型列出所需的列名称。
这是否比变通方法更麻烦或更少,在旁观者的眼中。
- ArduinoJson 6.15.2:JsonObject没有命名类型
- 防止主数据类型C++的隐式转换
- 大量序列中核苷酸类型的快速计数
- 如何从C++中的依赖类型中获得它所依赖的类型
- 有关插入适配器的错误。[错误]请求从 'back_insert_iterator<vector<>>' 类型转换为非标量类型
- 是否可以初始化不可复制类型的成员变量(或基类)
- 如何获取std::result_of函数的返回类型
- 从父命名空间重载类型
- 如果C++类在类方法中具有动态分配,但没有构造函数/析构函数或任何非静态成员,那么它仍然是POD类型吗
- 我想将一个对T类型的非常量左值引用绑定到一个T类型的临时值
- Openssl 1.1.1d无效使用不完整的类型"struct dsa_st"
- 访问者访问变体并返回不同类型时出错
- 在VS2010-VS2015下编译时,如何使用decltype作为较大类型表达式的LHS
- 处理小于cpu数据总线的数据类型.(c++转换为机器代码)
- C++ 雷神库 - 使用资源加载器类时出现问题(不命名类型)
- 模板元程序查找相似的连续类型名称
- 任何种类的分数 在任何类型的订单中
- 2 种模板相关类型种类的差异
- C++每帧更新和复制一系列值.我应该使用哪种类类型
- 在键上使用 map.find() 和 count(),这是一种类对象类型