0

I am working on a simple Windows::Forms GUI and am running into some issues trying to use STL vector and pair through the cliext package. Basically, I implemented a very simple (and naive) bidirectional map with an underlying cliext::vector< cliext::pair<A, B> >. I don't care about efficiency at all right now and all instances of it will hold only a handful of entries so my naive linear searches will not be an issue.

But, since I want to use these maps inside my Windows::Forms instance I made it a managed class. The problem is that I cannot figure out how to modify individual entries of my map.

Here is the basic interface (I put the function def's here for brevity):

template<class A, class B>
ref class bimap 
{
public:
    typedef typename cliext::vector< cliext::pair<A, B> >::const_iterator const_it;

    void Insert(const A & a, const B & b)
    {
        bmap.push_back(cliext::pair<A,B>(a,b));
    }

    bool SetInternalByLeftDirect(const A & search_for, const B & set_value)
    {
        for(int i = 0; i < bmap.size(); i++)
        {
             if(bmap[i].first == search_for)
             {
                  bmap[i].second = set_value;
                  return true;
             }
             return false;
        }
    }

    bool SetInternalByLeftWithIterator(const A & search_for, const B & set_value)
     {
        for(const_it it = bmap.begin(); it != bmap.end(); it++)
        {
             if((*it).first == search_for)
             {
                 (*it).second = set_value;
                  return true;
             }
             return false;
        }
    }

    bool SetExternalByLeft(const A & search_for, [Out] B % modify_external)
    {
        for(int i = 0; i < bmap.size(); i++)
        {
             if(bmap[i].first == search_for)
             {
                 modify_external = bmap[i].second;
                 return true;
             }
         }
         return false;
    }

private:
    cliext::vector< cliext::pair<A, B> > bmap;
};

Both SetInternal approaches do not work. The iterator approach just gives me a compile error where it says "left of first must be a class/struct/union..did you mean ->" but that doesn't make sense to me because Visual Studio already says it is wrong to use -> and when I use . IntelliSense even shows me "first" and "second" in the list.

The direct approach won't work either. It compiles and runs but it doesn't actually modify the value of the pair (even when it returns true!).

Moreover, I included the SetExternal function because that actually works fine. This tells me that searching through the bmap vector by indices works fine and the conditional on bmap[i] is fine and it can set the external variable.

Any thoughts on how I can write a SetInternal method to modify individual pairs in my vector? I also need a way to iterate through the bimap externally and I wanted to use a const iterator (i.e., have member methods that return a const iterator to the begin and end of the underlying bmap) but when I try to use it externally and dereference the iterator I get the same error as when I try to dereference the iterator in the SetInternalByLeftWithIterator method above.

Thank you!

kilgoretrout
  • 3,547
  • 5
  • 31
  • 46
  • If you are interfacing with pure C++ code that has `std::vector` in the interface, then sure, but if you are only dealing with C++/CLI, why not use .Net classes? – crashmstr Jan 23 '15 at 18:39
  • @crashmstr Hmm, I can try that but I was hoping to avoid dealing with them because this class is so simple and small. Would you recommend a .NET `List` of `Tuple`'s? Thanks. – kilgoretrout Jan 23 '15 at 18:55
  • The equivalent should be something like `List^>^`. It is in c#, but you might also take a look at [Two-way / bidirectional Dictionary in C#?](http://stackoverflow.com/a/10966684/1441). – crashmstr Jan 23 '15 at 18:59
  • @crashmstr also I just want to understand what is going on. Why does `bmap[i].first == search_for` work in all the conditionals correctly but I can't actually modify the value with `bmap[i].second = set_value`? – kilgoretrout Jan 23 '15 at 19:00
  • Not sure. Did not even know the STL/CLR stuff existed until I saw this question. – crashmstr Jan 23 '15 at 19:06
  • Yeah, that's what's driving me nuts here. That I can ACCESS the individual `pair`'s and their coordinates but I can't MODIFY them! – kilgoretrout Jan 23 '15 at 19:10

1 Answers1

0

Well, it turns out that if I replace my underlying vector with cliext::vector< cliext::pair<A,B>^ > and access the pairs with bmap[i]->first and bmap[i]->second then I can both access and modify. I guess the compiler error I got from using iterators was on to something.

Also this allows both the "direct" and "iterator" approach I outlined above.

I still have no idea why the original approach allowed access but not modification but C++CLI does give me a headache.

Thanks @crashmstr for your attention!

kilgoretrout
  • 3,547
  • 5
  • 31
  • 46