【问题标题】:Extending a thrift generated object in C++在 C++ 中扩展节俭生成的对象
【发布时间】:2011-08-01 16:10:44
【问题描述】:

使用以下.thrift文件

struct myElement {
  1: required i32 num,
}

struct stuff {
  1: optional map<i32,myElement> mymap,
}

我得到了一个带有 STL 映射的节俭生成的类。这个类的实例是长期存在的 (我使用 TSimpleFileTransport 将其追加和删除,以及将其写入磁盘)。

我想在 C++ 中扩展 myElement,扩展不应该影响 此对象的序列化版本(并且此对象未在任何 其他语言)。有什么干净的方法来完成它?

我考虑了以下内容,但它们看起来并不干净:

  1. 制作第二个使用相同键索引的非节俭映射
    • 保持两者同步可能会很痛苦
  2. 通过对生成的代码进行后处理来修改生成的代码 标头(包括前处理器骇客)。
  3. 与 #2 类似,但修改生成端以在生成的结构中包含以下内容,然后在强制包含的标头中定义 NAME_CXX_EXT
      #ifdef NAME_CXX_EXT
      NAME_CXX_EXT ...
      #endif
    

以上所有看起来都相当讨厌


我现在要采用的解决方案:

[这都是伪代码,没有检查这个副本进行编译]

以下生成的代码,我无法修改 (虽然我可以将地图更改为一组)

class GeneratedElement {
 public:
   // ...
   int32_t num;
   // ...
};


class GeneratedMap {
 public:
   // ...
   std::map<int32_t, GeneratedElement>  myGeneratedMap;
   // ...
};

// End of generated code

应用中的其他地方:

class Element {
 public:
   GeneratedElement* pGenerated; // <<== ptr into element of another std::map!
   time_t lastAccessTime;
};


class MapWrapper {
private:
  GeneratedMap theGenerated; 

 public:
   // ...
   std::map<int32_t, Element>  myMap;
   // ...

   void doStuffWIthBoth(int32_t key)
   {
     // instead of 
     //   theGenerated.myGeneratedMap[key].num++;  [lookup in map #1]
     //   time(&myMap[key].lastAccessTime);        [lookup in map #2]
     Element& el=myMap[key];
     el.pGenerated->num++;
     time(&el.lastAccessTime);
   }
};

我想避免每次访问都进行双重地图查找 (尽管我知道复杂性保持不变,但仍然是两次查找)。

我认为我可以保证对theGenerated 的所有插入和删除) 在一个地方完成,在同一个地方是我填充/删除的地方 myMap 中的相应条目,然后我就可以初始化 Element::pGenerated 到其在Generated.myGeneratedMap 中的对应元素

这不仅可以让我节省一半的查找时间,我什至可以改变 myMap 为我的 keytype 提供更好的容器类型(比如 hash_map 甚至是 boost 多索引图)

起初这对我来说是个坏主意。使用 std::vector 和 std::dqueue 我可以 看看这可能是一个问题,因为值将被移动, 使指针无效。鉴于 std::map 是用树实现的 结构,真的有一个地图元素会被重新定位的时候吗? (我的上述假设在enter link description here的讨论中得到了证实)

虽然我可能不会为 myElement 的每个成员或任何语法糖(如重载 [] () 等)提供访问方法,但这让我可以以几乎一致的方式对待这些元素。唯一的关键是(除了插入)我从不直接寻找mymap 的成员。

【问题讨论】:

    标签: c++ thrift


    【解决方案1】:

    您是否考虑过只使用简单的集装箱船?

    您使用的是 C++,因此您可以将结构体包装在某个类或其他结构体中,并提供包装器方法来做任何您想做的事情。

    【讨论】:

    • 如果我理解正确,您建议我将stuff 包装在另一个类中。如果是这样,它将如何帮助我扩展myElements?如果这不是你的意思 - 那么我想我需要一个例子。最后,似乎有很多访问方法需要开发,主要好处是外部用户的语法(糖)
    猜你喜欢
    • 1970-01-01
    • 2012-11-25
    • 1970-01-01
    • 1970-01-01
    • 2010-12-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多