代码之家  ›  专栏  ›  技术社区  ›  timday

如何打破这个圆形的typedef?

  •  7
  • timday  · 技术社区  · 15 年前

    我想声明两种类型 (在模板上的类的内部 K V 并提供一些缓存行为):

    typedef std::map<
      long long,
      typename key_to_value_type::iterator  // Ooops... not declared yet
    > timestamp_to_key_type;
    
    typedef std::map<
      K,
      std::pair<V,typename timestamp_to_key_type::iterator> 
    > key_to_value_type;
    

    当然这是不可能的,因为循环定义。 我可以用 void* ,但我想知道是否有一些前向声明魔术或其他技术,将做得更好。

    (是的,我知道 boost::bimap 会回避这个问题)。

    2 回复  |  直到 15 年前
        1
  •  7
  •   Peter Alexander    15 年前

    不可能,请考虑以下类型:

    timestamp_to_key_type
    = map< long long, key_to_value_type::iterator >
    = map< long long, map< K, pair< V, timestamp_to_key_type::iterator > >::iterator >
    = map< long long, map< K, pair< V, map< long long, map< K, pair< V, map< long long, map< K, pair < V ...
    

    这不是forward声明的问题,您只需简单地描述一个递归定义的类型。这和:

    struct A { B b; };
    struct B { A a; };
    

    解决这个问题的唯一方法是丢失一些静态类型信息。如你所说,你可以使用 void* ,或者您可以尝试定义自己的抽象类型擦除接口。你的选择。

        2
  •  1
  •   Roger PateRoger Pate    15 年前

    打破循环定义,其中只有一个包含V,另一个包含迭代器:

    typedef map<K, V> KVMap;
    typedef map<long long, typename KVMap::iterator> TSMap;
    

    如果需要使用密钥查找时间戳,而该时间戳未存储在V中,则可以在KVMap中复制该时间戳:

    typedef map<K, pair<V, long long> > KVMap;
    

    从K中,您可以使用KVMap::find,获取时间戳,然后使用TSMap::find并获取对应项的句柄(例如删除它)。