7

我想声明几种类型(在模板化的类内部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会回避这个问题)。

4

2 回答 2

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*,或者您可以尝试定义自己的抽象类型擦除接口。你的选择。

于 2010-11-12T22:38:37.563 回答
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 并获取相应项目的句柄(例如擦除它)。

于 2010-11-13T00:17:24.387 回答