我正在尝试实现一个数据结构来管理 n 维向量,其中 n 不会大于 50。
问题是n = 2是一个特殊情况,它具有相同的接口,但实现完全不同。我该如何实施?
我正在考虑将n设为模板参数,并且:
- 对 n = 2 进行部分模板特化
- 复制粘贴 n = 2 的界面
- 使用工厂构造数据结构,该工厂将为此结构的原型实例化 n = 2, 3, ..., 50
有没有更好的办法?如果我按照我的建议实施它,我应该注意什么?
我正在尝试实现一个数据结构来管理 n 维向量,其中 n 不会大于 50。
问题是n = 2是一个特殊情况,它具有相同的接口,但实现完全不同。我该如何实施?
我正在考虑将n设为模板参数,并且:
有没有更好的办法?如果我按照我的建议实施它,我应该注意什么?
IMO 为特殊情况 n=2 提供一种实现并为所有其他情况提供不同实现的工厂是实现它的最简单和最优雅的方式。
答案取决于n
是在编译时知道还是仅在运行时知道。
如果n
在编译时已知,那么部分模板规范就是要走的路(与std::vector<bool>
模板规范的实现相同)。
如果n
仅在运行时知道,您可以实现一个状态模式以将一个对象保留在执行操作的向量内部,对其进行两个实现,并将指向其实例的指针隐藏在向量对象内:
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
。如果不是这种情况,您可以在构造函数中分配 newVectorOperationsTwo
或VectorOperationsThreeAndMore
内部。
部分模板专业化。接口的共享部分可以从非模板化(或至少非专业化)基类继承。
原因是数据的维度在很大程度上不是运行时变量,而是依赖于域。
我认为容器尺寸在运行时是已知的,因此基于 teplate-specialization 的解决方案不起作用。
PIMPL成语呢?存储两种实现,一种用于一般情况,一种用于特殊情况。