Converting between the containers with transparent and non-transparent comparators

Issue

This Content is from Stack Overflow. Question asked by Weijun Zhou

I have a class A that has a member std::map<std::string, Data, std::less<>> where Data is another 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 only takes a std::map<std::string, Data>&. So I need to somehow convert from std::map<std::string, Data, std::less<>> to 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){
        //Something that 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 ...
};



Solution

Check the Answers

This Question and Answer are collected from stackoverflow and tested by JTuto community, is licensed under the terms of CC BY-SA 2.5. - CC BY-SA 3.0. - CC BY-SA 4.0.

people found this article helpful. What about you?