我正在尝试实现一个数据结构来管理n维向量,其中n不会大于50。
问题是 n = 2 是一个特殊情况,具有相同的接口,但实现完全不同。我该如何实现呢?
我正在考虑将 n 作为模板参数,并且:
有更好的方法吗?如果按照我的建议实施它,我应该注意什么?
答案 0 :(得分:3)
IMO工厂为特殊情况n = 2提供一个实现,而为所有其他情况提供不同的实现是最简单和最优雅的实现方式。
答案 1 :(得分:3)
答案取决于在编译时是否知道n
还是仅在运行时知道。
如果在编译时知道n
,则部分模板规范是可行的方式(与std::vector<bool>
的实现是模板规范的精神相同)。
如果仅在运行时知道n
,则可以实现State Pattern以保持向量内部的对象执行操作,对其进行两次实现,并隐藏指向其实例的指针在矢量对象内:
struct Vector;
struct VectorOperations {
virtual void doOperation1(Vector& v) = 0;
virtual void doOperation2(Vector& v) = 0;
};
struct VectorOperationsTwo: VectorOperations {
virtual void doOperation1(Vector& v);
virtual void doOperation2(Vector& v);
} opsTwo;
struct VectorOperationsThreeAndMore: VectorOperations {
virtual void doOperation1(Vector& v);
virtual void doOperation2(Vector& v);
} opsThreeAndMore;
class Vector {
VectorOperations *ops;
public:
Vector(int size) {
ops = size == 2 ? (VectorOperations*)&opsTwo : &opsThreeAndMore;
}
void operation1() {
ops->doOperation1();
}
void operation2() {
ops->doOperation2();
}
friend class VectorOperationsTwo;
friend class VectorOperationsThreeAndMore;
};
此示例假设两个元素的向量和两个以上元素的向量将具有相同的数据成员,因此我将opsTwo
和opsThreeAndMore
共享。如果不是这种情况,您可以在构造函数中分配新的VectorOperationsTwo
或VectorOperationsThreeAndMore
。
答案 2 :(得分:1)
我认为容器尺寸在运行时是已知的,因此基于teplate-specialization的解决方案不起作用。
PIMPL成语怎么样?存储两个实现,一个用于一般情况,一个用于特殊情况。
答案 3 :(得分:1)
部分模板专业化。接口的共享部分可以从非模板化(或至少非专用)基类继承。
原因是数据的维度非常不是运行时变量,而是依赖于域。