如何打破这个循环typedef?
我想声明几种类型 (在 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
会回避这个问题)。
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 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
这是不可能的,考虑一下类型是什么:
这不是前向声明的问题,您只是简单地尝试描述一个在其自身上递归定义的类型。这与:
解决这个问题的唯一方法是丢失一些静态类型信息。正如你所说,你可以使用
void*
,或者你可以尝试定义你自己的抽象的、类型擦除的接口。你的选择。It's not possible, consider what the types would be:
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:
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.打破循环定义,其中一个包含 V,另一个包含迭代器:
如果您需要使用键来查找时间戳,并且该时间戳未存储在 V 中,那么您可以在 KVMap 中复制它:
从 K 中,您可以使用 KVMap::find 获取时间戳,然后使用 TSMap::find 并获取相应项目的句柄(例如,擦除它)。
Break the circular definition with only one of them containing the V and the other containing the iterator:
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:
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).