2

I've the following C++ code:

struct MyStruct
{
    int a[2];
    int b[2];
};

std::map<std::pair<int, int> , MyStruct*> MyMap;

Now I run this loop on MyMap:

for(std::map<std::pair<int, int> , MyStruct*>::iterator itr = MyMap.begin(); itr != MyMap.end(); ++itr)
{
    std::pair<int, int> p (itr->first().second, itr->first().first);
    auto i = MyMap.find(p);
    if(i != MyMap.end())
    {
        //do something
    }
}

What I'm actually trying to do is forming a pair by swapping the elements of another pair , so for example I have a key pair(12,16) in MyMap and also another key pair(16,12); these two key exists in MyMap and I know for sure. But when I apply the above technique MyMap don't return the value corresponding to the swapped key, what I'm guessing that MyMap.find(p) is matching the pointer of Key; but is there a way so that I can force MyMap.find(p) to match the corresponding value in Key (pair) instead of matching the pointers in Key (pair) ? Or is there anything I'm doing wrong here ?

awesoon
  • 32,469
  • 11
  • 74
  • 99
user963167
  • 21
  • 1
  • 4
  • 3
    You know that if you write "using namespace std" you will not have to write std:: everytime? Only a side note to help you. – cerkiewny May 23 '13 at 04:11
  • I know it ,just to clarify the code :) – user963167 May 23 '13 at 04:13
  • 6
    @cerkiewny, `using namespace std` has a lot of side-effects. Do not use it. – awesoon May 23 '13 at 04:15
  • For me you are using the find on the newly created pointer to the std:pair p. And it will compare the addresses of the "p" pointer and those existing in your map, so the code will never find the actual "p" in your map. – cerkiewny May 23 '13 at 04:19
  • @cerkiewny http://stackoverflow.com/questions/1452721/why-is-using-namespace-std-considered-bad-practice – pyCthon May 23 '13 at 04:19
  • @soon I am aware of that but the problem here is not sophisticated so i thought that the op is not aware of the namespace usage idea. – cerkiewny May 23 '13 at 04:21
  • @cerkiewny better if they are not aware of that. It is a terrible idea. – juanchopanza May 23 '13 at 05:33

1 Answers1

1

You have some imprecisions in your code, say, your MyStruct does not have a copy constructor, but contains arrays, itr->first() in your for loop, while first doesn't have a call operator, and others. The following code does what you want:

#include <array>
#include <map>
#include <utility>
#include <memory>
#include <stdexcept>
#include <iostream>

struct MyStruct
{
    std::array<int, 2> a;
    std::array<int, 2> b;
};

template <class T, class U>
std::pair<U, T> get_reversed_pair(const std::pair<T, U>& p)
{
    return std::make_pair(p.second, p.first);
}

int main()
{
    std::map<std::pair<int, int>, std::shared_ptr<MyStruct>> m
    {
        {
            {12, 16},
            std::make_shared<MyStruct>()
        },
        {
            {16, 12},
            std::make_shared<MyStruct>()
        }
    };

    std::size_t count = 1;

    for(const auto& p: m)
    {
        try
        {
            auto f = m.at(get_reversed_pair(p.first));
            f -> a.at(0) = count++;
            f -> b.at(0) = count++;
        }
        catch(std::out_of_range& e)
        {

        }
    }

    for(const auto& p: m)
    {
        std::cout << p.first.first << ' ' << p.first.second << " - ";
        std::cout << p.second -> a.at(0) << ' ' << p.second -> b.at(0) << std::endl;
    }

    return 0;
}

Output:

12 16 - 3 4
16 12 - 1 2
awesoon
  • 32,469
  • 11
  • 74
  • 99
  • There's no guarantee that MyStruct object for pair(12, 16) and (16, 12) will be same rather different ; but in My case what was happening that pair (12, 16) returns value from map but when I dynamically swap it to pair (16, 12) it returns MyMap.end() iteration (means key not found) even though Key(16, 12) exists in MyMap – user963167 May 23 '13 at 05:18
  • @user963167, They will be different - of course. But I see no problems, when I swap two objects([live example](http://coliru.stacked-crooked.com/view?id=d8de1cca4768954d4e88638d4a622f3a-ff683aff19d685e086e79e4ef634f9fb)). If you remove `break` statement from last but one for loop, you will see, that output differs - this means, that those objects has been swapped again. – awesoon May 23 '13 at 05:37
  • @user963167 if it returns `MyMap.end()` then pair(16,12) is not in the map, period. You must have a bug elsewhere, in the code you are not showing (besides the bugs you have in the code you posted, which have already been pointed out). – juanchopanza May 23 '13 at 05:38
  • for(const auto& p: m) Visual Studio 2010 throws compiler error "error C3531: 'p': a symbol whose type contains 'auto' must have an initializer" – user963167 May 23 '13 at 07:34
  • Range based for is a C++11 feature. MSVS 2010 doesn't support it. – awesoon May 23 '13 at 07:44