我想做这样的事情:
template<typename CType, unsigned int targetDimensions> struct GeneratePointerType
{
typedef typename GeneratePointerType<CType, targetDimensions-1>::type* type;
static const unsigned int dimensions = GeneratePointerType<CType, targetDimensions-1>::dimensions+1;
};
template<typename CType> struct GeneratePointerType<CType, 0>
{
typedef CType type;
static const unsigned int dimensions = 0;
};
Dictionary<int, GeneratePointerType<int, valueDimensions>::type >
所以基本上我想为指针类型实例化一个容器模板,但我不知道在运行时之前创建的指针的指针级别,所以从上面的方法当然不能编译,因为“维度”不是编译时常量。
有没有办法(与纯C ++ 03兼容,没有任何C ++ 11功能)来实现预期的行为?
编辑: “如果你能告诉我们真正的问题,我们可能会有更好的解决方案。” “那么澄清一下,你想要一个N维数组/对象的映射,其中N是一个运行时值?Wierd。我无法想象一个用例” 好的,让我告诉你一些关于用例的话:
我有一个类Template Dictionary,它基本上就像C#或Java Dictionary泛型一样。
该类用于围绕C库的C ++包装器库。
因此我有转换函数,它在C ++容器类的实例和C容器结构的实例之间转换数据。
如你所知,C没有泛型,所以在C ++中我可以像这样创建容器:
Dictionary<int, int**> dict;
在C中我必须这样做:
CDictionary dic;
dic.keytype = TYPECODE_INT;
dic.valuetype = TYPECODE_INT;
dic.valueDimensions = 2;
现在,当将C字典转换为C ++字典时,我在如何生成正确数量的*方面很困难,因为存储在C字典中的信息不是编译时常量。
EDIT2: 实际上,我从底层C接口获取运行时维度计数并不重要,因为C lib从序列化数据创建那些结构,这些结构来自网络,并且在编译时无法知道lib,数组中有多少个数组 - 来自另一个应用程序的网络,可能是另一个编程语言,反序列化的C ++实现仍然需要根据有关数组维度的运行时信息确定字典的值类型
EDIT3: “好吧,我认为你需要说明你想如何使用这个结构,因为我显然没有正确解释你的问题,而且这些信息都不在问题中。你能编辑一些伪代码来展示你正在尝试的东西吗?实现?” 呼叫公共接口:
Dictionary<int, int*> dic;
int* arr = new int[10];
dic.put(1, arr, a0);
delete arr;
send(dic); // dic gets serialized and sent over the netwowork
当收到序列化的dic时,我想在将其传递给回调之前对其进行反序列化:
// read out typecodes and dimnesions from the serialized data
// [...]
// create the Dictionary from that info
switch(valueTypeCode)
{
case TYPECODE_SHORT:
return new Dictionary<int, GeneratePointerType<short, valueDimensions>::type>[size]();
case TYPECODE_INTEGER:
return new Dictionary<int, GeneratePointerType<int, valueDimensions>::type>[size]();
}
// fill it with the deserialized payload afterwards
// [...]
答案 0 :(得分:0)
如果参数N
在编译时未知,则无法使其成为静态类型的一部分。因此,您必须使用某种类型的运行时调度。
可能的选择是:
简单地包装C
结构(提供运算符重载和其他方法,封装底层数据)并以完全相同的方式访问它
class Dictionary {
CDictionary *inner;
public:
// C++ syntactic sugar here
};
如果N
以超出一些合理的值(例如,您可以假定N < 10
),则可以为每个有效N实例化一个模板类,它实现了一个抽象接口。然后,您的模板实例将隐藏在翻译单元中,该单元仅公开公共(虚拟)接口和工厂功能;实际访问使用运行时多态性
class AbstractDictionary {
public:
virtual ~AbstractDictionary() = 0;
// virtual methods
};
AbstractDictionary* wrap(CDictionary *);