0

I'm trying to implement a simple bidirectional map data structure. I found this helpful link and I decided to implement it in the second way stated in the accepted answer. My code:

BiMap.h

template <typename X, typename Y>
class Comparator
{
public:
    bool operator() (const std::pair<X, Y*>& e1, const std::pair<X, Y*>& e2) const;
};

template <typename T1, typename T2>
class BiMap
{
public:
    void insert(const T1& a, const T2& b);
private:
    std::set<std::pair<T1, T2*>, Comparator<T1, T2*>> map1_;
    std::set<std::pair<T2, T1*>, Comparator<T2, T1*>> map2_;
};

BiMap.cpp

template <typename X, typename Y>
bool Comparator<X, Y>::operator() (const std::pair<X, Y*>& e1, const std::pair<X, Y*>& e2) const
{
    return e1.first < e2.first;
}

template <typename T1, typename T2>
void BiMap<T1, T2>::insert(const T1& t1, const T2& t2)
{
    auto itr1 = map1_.emplace(t1, nullptr).first;
    auto itr2 = map2_.emplace(t2, nullptr).first;
    itr1->second = &(itr2->first);      // ERROR
    itr2->second = &(itr1->first);      // ERROR
}

main.cpp

int main()
{
    BiMap<int, string> M;
    M.insert(1, "one");
}

On compilation, I'm getting the following error:

c:\users\lucieon\source\repos\algorithms\trie\trie\suffixtree.inl(17): error C2440: '=': cannot convert from 'const _Ty1 *' to 'const _Ty2'
1>        with
1>        [
1>            _Ty1=std::string
1>        ]
1>        and
1>        [
1>            _Ty2=std::string *
1>        ]
1>c:\users\lucieon\source\repos\algorithms\trie\trie\suffixtree.inl(17): note: Conversion loses qualifiers
1>c:\users\lucieon\source\repos\algorithms\trie\trie\suffixtree.inl(12): note: while compiling class template member function 'void trie::BiMap<int,std::string>::insert(const T1 &,const T2 &)'
1>        with
1>        [
1>            T1=int,
1>            T2=std::string
1>        ]
1>c:\users\lucieon\source\repos\algorithms\trie\trie\trie.cpp(140): note: see reference to function template instantiation 'void trie::BiMap<int,std::string>::insert(const T1 &,const T2 &)' being compiled
1>        with
1>        [
1>            T1=int,
1>            T2=std::string
1>        ]
1>c:\users\lucieon\source\repos\algorithms\trie\trie\trie.cpp(139): note: see reference to class template instantiation 'trie::BiMap<int,std::string>' being compiled
1>c:\users\lucieon\source\repos\algorithms\trie\trie\suffixtree.inl(18): error C2440: '=': cannot convert from 'const _Ty1 *' to 'const _Ty2'
1>        with
1>        [
1>            _Ty1=int
1>        ]
1>        and
1>        [
1>            _Ty2=int *
1>        ]
1>c:\users\lucieon\source\repos\algorithms\trie\trie\suffixtree.inl(18): note: Conversion loses qualifiers

I understand that itr1->first and itr2->first are part of the const key for map1_ and map2_ respectively and probably that's why I'm getting this error but this is the only way I can make this data structure work. Is there any simple work around for this?

Community
  • 1
  • 1
srt1104
  • 959
  • 7
  • 11

1 Answers1

0

you cannot modify std::set elements after the fact as it simply could no longer ensure uniqueness then. It seems you want to have a std::map. Now the question is what do you want as your key and what as your value. When you start using pointers the question arises who owns the objects and whether they will always remain at the exact address.

Starting point might be:

std::map<T1, const T2*, Comparator<T1, T2*>> map1_;
std::map<T2, const T1*, Comparator<T2, T1*>> map2_;

...

auto itr1 = map1_.emplace(t1, &t2).first;
auto itr2 = map2_.emplace(t2, &t1).first;