Bartek's “Idea 1” is good (although there is no good reason to prefer from unordered_map to map ).
Alternatively, you can have std::map<C2, Data*> or std::map<C2, std::map<C1, Data>::iterator> to allow direct access to Data objects after a single C2 search, but then you need to be more careful not to get access to invalid (erased) Data (more precisely, before erase from both containers is atomic from the point of view of any other users).
It is also possible that one or both map move to shared_ptr<Data> - others could use weak_ptr<> if it is useful for ownership. (This is in the C ++ 11 standard, otherwise the obvious source - boost - seems to be for you, but maybe you implemented your own or chose a different library? Pretty fundamental classes for modern C ++).
EDIT - Hash Tables and Balanced Binary Trees
This is not particularly relevant to the issue, but received comments / interest below, and I need more space for it to be resolved correctly. Some moments:
1) Bartek does not recommend changing from map to unordered_map without recommending impact research. Reusing an iterator / pointer is dangerous and unreasonable if there is no reason to think that it is necessary (the question does not mention performance) and there are no recommendations for the profile.
3) A relatively small number of data structures in the program are important for critical behavioral characteristics, and there are many times when the relative performance of one against the other is of little interest. Supporting this claim - the masses of code were written using std::map to ensure portability to C ++ 11 and to perform just fine.
4) When performance is a serious issue, the advice should be “Care => profile”, but, saying that the rule of thumb is ok - according to “Don't pessimize prematurely” (see, for example, Sutter and Alexandrescu C ++ Coding Standards ) - and if asked, I would gladly recommend unordered_map by default, but this is not particularly reliable. It seems to me that the world does not recommend recommending every use of std::map .
5) This side track of container performance began to extract special pieces of useful information, but far from complete or balanced. This question is not a reasonable place for such a discussion. If there is another question regarding this, when it makes sense to continue this discussion, and someone asks me to come in, I will do this within the next month or two.