构造不同类型的C++向量数组
Constructing array of C++ vectors of different types
有没有一种很好的方法来构造不同类型的std::vector数组?还有没有存储这些向量的好方法?
例如,让我们有一些结构体Foo
、Bar
和Baz
。我想创建一个容器类Cont
,其中包含Foo
、Bar
、Baz
向量的某种组合。下面的代码将实现这一点,但我有一些问题。
#include <vector>
// arbitrary structs
struct Foo{ int var1; };
struct Bar{ double var1; double var2; };
struct Baz{ char var1; float var2; };
enum Mask{
fooMask = (1<<0),
barMask = (1<<1),
bazMask = (1<<2)
};
class Cont{
void** containers;
public:
Cont(int mask){
// count number of 1s in mask
int count = 0;
int countMask = mask;
while(countMask){
countMask &= countMask-1; // unset rightmost 1
count++;
}
containers = new void*[count];
int index = 0;
if((mask & fooMask) == fooMask)
containers[index++] = new std::vector<Foo>;
if((mask & barMask) == barMask)
containers[index++] = new std::vector<Bar>;
if((mask & bazMask) == bazMask)
containers[index++] = new std::vector<Baz>;
}
};
int main(){
// example construction
Cont c1(fooMask);
Cont c2(barMask|bazMask);
return 0;
}
首先,我不喜欢我必须将向量数组存储在空白**中,但我找不到更好的方法。
其次,如果我添加一个名为Qux
的新结构,我将不得不修改Cont
构造函数。最好是为了可维护性,我希望构造数组,而不必将结构类型硬编码到Cont
类中。
我尝试使用模板来解决这个问题,但找不到我满意的解决方案。我担心Cont
成为模板,因为我认为这会导致每个结构组合的模板膨胀。此外,我将有多个Cont
对象,但每个组合中只有一个我需要。
您可以使用类型擦除。
struct ContainerBase
{
virtual ~ContainerBase() = 0;
// This is where you can add an interface for common functionality.
// Write the pure virtual functions here and implement/override them in ContainerTyped.
};
inline ContainerBase::~ContainerBase() = default;
template<class T>
struct ContainerTyped : public ContainerBase
{
std::vector<T> values;
};
class Cont
{
std::vector<std::unique_ptr<ContainerBase>> containers;
public:
Cont(int mask) {
// ...
if ((mask & fooMask) > 0)
containers.push_back(std::make_unique<ContainerTyped<Foo>>());
if ((mask & barMask) > 0)
containers.push_back(std::make_unique<ContainerTyped<Bar>>());
}
};
演示
这可能比使用例如std::any
或其他预先存在的类型擦除,因为 1( 您指定只能存储特定的东西(您的矢量容器(,以及 2( 您可以按照指示添加通用接口,甚至可以将接口功能专用于不同的ContainerTyped
。但是我们需要更多地了解您的用例,以详细说明此优势。
void*
的问题始终是您需要以某种方式保留有关实际存储的内容的信息,因为您正在绕过强类型系统。换句话说,如何将存储的东西放回强类型系统中?这正是上述方法可以大放异彩的部分,因为您可以在ContainerBase
中添加virtual print() = 0
,然后为每种结构创建专用版本,例如
template<>
void ContainerTyped<Foo>::print()
{
for (Foo& foo : values) {
// Print Foo objects as you wish!
}
}
就添加Qux
结构时不必接触Cont
构造函数而言,显然仍然需要以某种方式对"哪个掩码位属于哪个结构"的信息进行编码,但您可以从Cont
构造函数中提取它(甚至将其隐藏在不同的翻译单元中(:
// Put this implementation wherever, Cont only has to know the signature.
std::unique_ptr<ContainerBase> makeContainer(int mask, unsigned indexBit)
{
if ((mask & fooMask) > 0)
return std::make_unique<ContainerTyped<Foo>>();
// etc.
if ((mask & quxMask) > 0)
return std::make_unique<ContainerTyped<Qux>>();
return nullptr;
}
// ...
Cont::Cont(int mask)
{
for (unsigned indexBit = 0; indexBit < 8; ++indexBit) {
auto container = makeContainer(mask, indexBit);
if (container)
containers.emplace_back(std::move(container));
}
}
你可以通过其他方式对枚举 -> 类型信息进行编码,但这超出了这个问题的范围。关键是您可以将具体类型隐藏在ContainerBase
后面,并在您想要引用"这些容器中的任何一个"的任何地方使用它。
- 写入向量<向量<bool>>
- 函数向量_指针有不同的原型,我可以构建一个吗
- std::向量与传递值的动态数组
- 将值指定给向量(2D)的向量中的某个位置
- 找不到成员对象:没有名为get_event()的成员,也处理多态性和向量
- 如何使用向量的template_back函数
- 尝试通过多个向量访问变量时,向量下标超出范围
- 如何通过派生类函数更改基类中的向量
- C++从另一个类访问公共静态向量的正确方法是什么
- 如何将ampl中的集合表示为c++中的向量
- 变量没有改变?通过向量的函数调用
- 迭代时从向量和内存中删除对象
- 向量 <int> a {N, 0} 和 int arr a[N] = {0} 的时间复杂度有什么区别
- 如何为模板化对象创建模板向量?VS正在投掷C3203
- 计算排序向量的向量中唯一值的计数
- 矩阵向量乘法(cublasDgemv)返回零
- 一对向量构造函数:初始值设定项列表与显式构造
- 将结构向量排序为子组
- 在C++中调整向量中的索引
- 向量元素的引用地址与它所指向的向量元素的地址不同.为什么