如何打破这个循环typedef?

时间:2010-11-12 22:28:45

标签: c++ stl iterator typedef forward-declaration

我想宣布几种类型 (在KV上模板化的类的内部,并提供一些缓存行为):

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 个答案:

答案 0 :(得分:7)

这是不可能的,请考虑类型:

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 ...

这不是前向声明的问题,您可以简单地尝试描述在其自身上递归定义的类型。它没有什么不同:

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

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

答案 1 :(得分:1)

打破循环定义,其中只有一个包含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并获取相应项目的句柄(例如擦除它)。