【发布时间】:2017-12-21 11:14:24
【问题描述】:
我有一个由模板类型组成的结构,它可以处理不完整的类型,除非实例化,例如std::vector。使用类型安全索引包装器访问这些类型。示例:
template<class T>
struct Idx{unsinged val;};
struct Holder{
MyVector<Foo> foos;
MyVector<Bar> bars;
};
const Foo& foo = holder.foos.get(Idx<Foo>(...));
这很好用:Idx 不需要知道模板参数的类型,因为它从未使用过。 Holder 也适用于 Foo/Bar 的前向声明。我不能将Idx<Foo> 与Idx<Bar> 混淆,因为我只能用它们获得相应的类型。因为这太独特了,所以我想为持有者添加便利功能:
struct Holder{
MyVector<Foo> foos;
MyVector<Bar> bars;
const Foo& get(Idx<Foo> idx) { return foos.get(idx);}
const Bar& get(Idx<Bar> idx) { return bars.get(idx);}
};
但现在我需要 Holder 的完整类型,而我想避免这种情况。是否可以使用不完整类型和便利功能?也许一些模板会有所帮助,但我需要一些调度到最有可能实例化它的 foos 或 bar。
【问题讨论】:
-
我打电话给XY Problem。我认为您的要求是其他错误设计决策的结果。让“类型安全索引包装器”
Holder同时负责多个集合类型是很奇怪的,而不是将类型安全索引包装器设计为一个通用向量/索引的集中功能,然后多次使用它。 -
让我澄清一下:索引包装器称为
Idx,它可以以类型安全的方式从集合MyVector中获取实例。Holder是不同类型的MyVector的集合。Foo和Bar可能不相关但经常一起使用或相关(Foo包含Idx<Bar>)还有另一种解决方案:让 Foo/Bar 从 Base 继承,将它们作为 Base-Ptrs 存储在单个容器中并使用Idx中的类型将它们静态转换为它们的类型。但我不想那样。我为每个 Foo 实例命名以获取它的索引,并且使用它需要所有 Foo/Bar 实例的唯一名称。