我在C ++中设计了一个快速基本的矢量运算库。当我需要快速交叉乘积或向量之间的角度时,我从命令行调用程序。我不使用Matlab或Octave或相关,因为启动时间大于计算时间。同样,这是非常基本的操作。
我正在扩展这个程序,我将把它作为RPN计算器,用于类型的操作:
1 2 3
4 5 6
x
out: -3 6 -3
(给一个向量,另一个向量和“交叉”运算符;吐出十字产品)
堆栈必须接受3d向量或标量,用于以下操作:
1 2 3
2
*
out: 2 4 6
这个迷你计算器的词法分析器和解析器是微不足道的,但我似乎无法想到创建内部堆栈的好方法。你将如何创建一个包含向量或双精度的堆栈(我卷起了我自己非常简单的向量类 - 少于一百行,它可以完成我需要的所有内容。)
如何创建一个接受Vector类元素或类型为double的简单堆栈?
谢谢。
答案 0 :(得分:3)
你看过boost::any吗?
答案 1 :(得分:3)
一种解决方案是使用工会。使用联合,您可以将不同结构的内存区域使用相同的内容。例如,您可以将一个double和一个struct结合在一起。它们共享相同的内存,您只能使用其中一个。你可以使用一些枚举来告诉使用哪一个。
工会有点hacky,因为他们使用对象更棘手。编译器不知道如何构造,破坏或复制它们,因为许多对象可能共享相同的内存。下面是一个小例子,如果我想节省内存,我会怎么做(好吧,枚举占用四个字节因此不是内存效率,但让我们忘记了;)
#include <cstdlib>
#include <iostream>
struct Vector
{
double x, y, z;
};
struct Element
{
enum Type { SCALAR, VECTOR };
Type type;
union {
double scalar;
Vector v;
} data;
};
int main(void)
{
Element vector_element;
vector_element.type = Element::VECTOR;
vector_element.data.v.x = 1;
vector_element.data.v.y = 2;
vector_element.data.v.z = 3;
Element scalar_element;
scalar_element.type = Element::SCALAR;
scalar_element.data.scalar = 3.142;
std::cout << "The size of type Element without enum would be: " << (sizeof(Element) - sizeof(Element::Type)) << " bytes." << std::endl;
return EXIT_SUCCESS;
}
顺便说一句,由于一些奇怪的原因,这导致了28个字节。我预计3 * 8 = 24字节。
答案 2 :(得分:1)
最简单的方法是创建一个Operand
结构,其中包含标量的double
和向量的Vector
对象:
struct Operand
{
double scalar_;
Vector vector_;
bool isVector_;
};
(如果它是一个向量操作数,你可以将isVector_
设置为true,如果它是一个标量操作数,则设置为false)
对于实际堆栈,您只需使用std::stack<Operand>
。
其他选项包括继承(创建从操作数基类型派生的标量和向量类型)或类似boost::variant
之类的东西,但对于像这样简单的东西,像上面显示的Operand
这样的组合结构可能是最简单的方法。