Is it possible to make return type of a function depends on some condition about type in template of a class?
Example
I have a custom hash map, named MyHashMap.
It has a proper begin(), and end() function that return iterator.
template <class K, class T> class MyHashMap{
MyIterator<K,T> begin() { ..... }
MyIterator<K,T> end() { ...... }
//.... some function ....
}
And the iterator has a neat operator*(), operator++(), etc
template <class K, class T> class MyIterator{
std::pair<K,T> operator*(){ ..... }
//.... some function ....
}
Now I can use MyHashMap in place of the std::unordered_map, so good.
Question:
Can I also extend this class to replace std::hashset too? How?
Specifically, I want to replace std::hashset and std::unordered_map with this class directly.
Motivation:
Both data structure (map & hashset) seems to be very similar (both code & logic), stuff them in one place can increase maintainability.
Difficulty:
The problem is that there are many hundreds times call Hash set like this:-
std::hashset<X> hashset; //old code, will be deleted
MyHashMap<X, MyHashMap_DUMMY > hashset; // new code
for(auto x: hashset ){
x.doSomething(); //# old code, compile error, but I don't want to change this
}
I can't change the return signature of hash map either because there are some codes that use it as a real map, not set:-
for(auto xy: hashmap ){ //HashMap<X,Y>
x.first.doSomething(); //# I don't want to change this line too
}
Note: Some lines (#) should not be changed. The reasons are :-
They appear in many places.
Changing them also make code dirty.
In future I may want to replace MyHashMap/MyHashSet back to std::unordered_map/std::hashset later.
If I don't modify #-line, there is little work to be done to change back (High modularity & maintainability).
My poor solution:
Create a MyHashSet to encapsulate HashMap. Its disadvantage is that I will have another layer of abstraction, have two classes, more bugs and less maintainability.
I wish there is a trick that can exploit / manipulate template to detect that T is MyHashMap_DUMMY.
In other words,
- If T == MyHashMap_DUMMY, the iterator->operator*() will return K&
- Else the iterator->operator*() will return std::pair.
C++11 and C++14 are allowed.