如何打破这个循环typedef?

发布于 2024-10-02 08:37:14 字数 483 浏览 5 评论 0原文

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

I want to declare a couple of types
(internal to a class templated on K and V and providing some caching behaviour):

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;

Of course this isn't possible as is, because of the circular definition.
I could hack it with a void*, but I'm wondering if there's some forward-declaration magic or other technique which will do the job better.

(Yes I am aware a boost::bimap would sidestep the problem).

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

野侃 2024-10-09 08:37:14

这是不可能的,考虑一下类型是什么:

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

It's not possible, consider what the types would be:

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

This is not a problem with forward declarations, you are simple trying to describe a type that is recursively defined on itself. It's no different than:

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

The only way to get around this is to lose some static type information. As you said, you can use void*, or you can try to define your own abstract, type-erased interface. Your choice.

高冷爸爸 2024-10-09 08:37:14

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

Break the circular definition with only one of them containing the V and the other containing the iterator:

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

If you need to use a key to look up a timestamp, and that timestamp isn't stored in V, then you can duplicate that in KVMap:

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

From a K, you can use KVMap::find, get the timestamp, and then use TSMap::find and get a handle on the corresponding item (e.g. to erase it).

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文