我需要在c ++中存储一组int和double(代表名义和实际值数据)。我显然可以将它们存储在std::vector<double>
中,但这感觉有点不对,并没有获得美学奖励积分。
我也可以根据多态做饭,但我也需要这个集合真正有效:存储和检索集合中的数据应该尽可能快。我发现很难判断这样的解决方案是否最有效率。
我还找到了boost::variant,这可能会有所帮助。
附加信息:集合中的项目数量很少(<100),并在初始化集合时已知。
总结:我显然可以通过无数方式解决这个问题,但我不确定在(i)效率是否非常重要以及(ii)我还想编写一些不错的代码时,什么是一个好的解决方案。我最好的选择是什么?
编辑,附加信息:集合代表较大数据集中的“行”,其元素代表某些“列”的值。行的属性是已知的,因此知道在哪个位置存储什么类型的数据。我所讨论的'效率'主要是检索某列的int / double值的效率,尽管快速设置值也很重要。我有一些函数可以对需要尽快检索的数据进行操作。例如:
typedef std::vector<double> Row;
void doubleFun(Row const &row)
{
// Function knows there's always a double at index 0
double value = row[0];
...
}
void integerFun(Row const &row)
{
// Function knows there's always an integer at index 1
int value = row[1];
...
}
经过一番思考和阅读建议到目前为止,似乎只是将int列和双列存储在两个单独的向量中是一个可靠的解决方案。然后,集合Row
可以定义两个不同的成员,用于检索函数可以使用的名义和实际数据。
只是存储为vector<double>
我猜也好,但这取决于double和int之间的转换速度有多快(这可能相当令人印象深刻)。
对于一开始有点不清楚感到抱歉,我希望现在更清楚了,我可以对此事有更多想法。
答案 0 :(得分:5)
在您的容器中订购一个重点吗?
如果不是这样的话:
class MyContainer
{
std::vector<double> doubles;
std::vector<int> ints;
push(double value) { doubles.push_back(value); }
push(int value) { ints.push_back(value); }
....
};
迭代器部分(浏览整个容器)可能有点棘手......
答案 1 :(得分:5)
为什么不直接使用double的向量?由于整数可以转换为双精度而不会损失精度......它在我看来是最简单,最有效的解决方案。
还有什么要设置(我无法从你的问题中找出)你如何区分正常值和实际值。在您可能选择的任何解决方案中,问题仍然存在。
答案 2 :(得分:3)
您可以使用联合类型并在向量中使用它。但在这种情况下,您必须有一些方法可以知道向量的哪些元素应该被视为整数,哪些元素应该被视为双精度。要跟踪哪些是整数以及哪些是双精度数,您可以使用bitset或类似的东西。
我不确定你的目标是避免重浮点计算。如果是,那么bitset可能更有效。如果没有,并且精确的int精度并不重要,那么你也可以将它们全部存储为双精度。
#include <vector>
#include <bitset>
union di
{
double d;
int i;
};
int main(int argc, char* argv[])
{
std::bitset<2> bitsetInts;
std::vector<di> v;
di e1;
e1.d = 3.9;
v.push_back(e1);
di e2;
e2.i = 3;
bitsetInts.set(1);
v.push_back(e2);
return 0;
}
答案 3 :(得分:3)
我会选择boost::variant
解决方案,它完全符合您的需求。
答案 4 :(得分:1)
有一个boost元组,如果你在编译时知道类型,你可以使用它。但是如果项目数量很少,那么浪费100个字节就不会有效。