Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to break this circular typedef?

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

like image 356
timday Avatar asked Nov 12 '10 22:11

timday


1 Answers

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.

like image 57
Peter Alexander Avatar answered Oct 08 '22 00:10

Peter Alexander