I have a class A that has a member std::map<std::string, Data, std::less<>> where Data is another class from a library whose source code I'd rather leave intact. I have opted in to use the transparent comparator by using std::less<> as the template argument since I want to be able to benefit from std::string_view.
The library can only take a std::map<std::string, Data>&. So I need to somehow convert between std::map<std::string, Data, std::less<>> and std::map<std::string, Data>. However, these two types are unrelated from the C++ language point of view, even though the internal structure of rb tree would be exactly the same (assuming the implementation uses rb tree to implement std::map, but that's just implementation detail), so directly casting will fail.
So is the following snippet the best way to achieve the goal or is there a better way to perform such a conversion?
#include <map>
#include <string>
#include <string_view>
#include <optional>
// Inside the library
namespace Library{
class Data {
//...
};
typedef std::map<std::string, Data> DataMap_t;
void processMap(DataMap_t& map){
//Mutates Data inside the map based on map key and other info
}
}
// In the application code
class A{
public:
typedef std::map<std::string, Library::Data, std::less<>> TransparentDataMap_t;
void processMap(){
Library::DataMap_t dataMap;
// This doesn't work, of course
//dataMap = static_cast<Library::DataMap_t>(transparentDataMap);
dataMap.merge(transparentDataMap);
Library::processMap(dataMap);
transparentDataMap.merge(dataMap);
}
std::optional<Library::Data> dataAt(std::string_view sv){
const auto iter = transparentDataMap.find(sv);
if(iter == transparentDataMap.end()){
return {};
}
return iter->second;
}
//Other member functions ...
private:
TransparentDataMap_t transparentDataMap;
//Other data members ...
};