C ++:从运行时维度信息创建Pointertype

时间:2012-08-01 16:02:57

标签: c++ templates generics generic-programming

我想做这样的事情:

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
// [...]

1 个答案:

答案 0 :(得分:0)

如果参数N在编译时未知,则无法使其成为静态类型的一部分。因此,您必须使用某种类型的运行时调度。

可能的选择是:

  1. 简单地包装C结构(提供运算符重载和其他方法,封装底层数据)并以完全相同的方式访问它

    class Dictionary {
        CDictionary *inner;
    public:
        // C++ syntactic sugar here
    };
    
  2. 如果N 超出一些合理的值(例如,您可以假定N < 10),则可以为每个有效N实例化一个模板类,它实现了一个抽象接口。然后,您的模板实例将隐藏在翻译单元中,该单元仅公开公共(虚拟)接口和工厂功能;实际访问使用运行时多态性

    class AbstractDictionary {
    public:
        virtual ~AbstractDictionary() = 0;
        // virtual methods
    };
    AbstractDictionary* wrap(CDictionary *);