【问题标题】:C++ std::map and std::pair<int, int> as KeyC++ std::map 和 std::pair<int, int> 作为键
【发布时间】:2013-05-23 04:09:38
【问题描述】:

我有以下 C++ 代码:

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

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

现在我在 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
    }
}

我实际上要做的是通过交换另一对的元素来形成一对,例如,我在 MyMap 中有一个密钥对(12,16),还有另一个密钥对(16,12);这两个键存在于 MyMap 中,我确定。但是当我应用上述技术 MyMap 不返回对应于交换键的值时,我猜测 MyMap.find(p) 与 Key 的指针匹配;但是有没有办法让我可以强制 MyMap.find(p) 匹配 Key (pair) 中的相应值,而不是匹配 Key (pair) 中的指针?还是我在这里做错了什么?

【问题讨论】:

  • 你知道如果你写“使用命名空间std”你就不必每次都写std::?只是一个旁注可以帮助你。
  • 我知道,只是为了澄清代码:)
  • @cerkiewny, using namespace std 有很多副作用。不要使用它。
  • 对我来说,您正在使用 find 新创建的指向 std:pair p 的指针。它会比较“p”指针的地址和地图中现有的地址,因此代码永远不会在地图中找到实际的“p”。

标签: c++ map stl std-pair


【解决方案1】:

您的代码中有一些不精确,例如,您的 MyStruct 没有复制构造函数,但包含数组,itr-&gt;first() 在您的 for 循环中,而 first 没有调用运算符,以及其他.以下代码可以满足您的要求:

#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;
}

输出:

12 16 - 3 4
16 12 - 1 2

【讨论】:

  • 无法保证 pair(12, 16) 和 (16, 12) 的 MyStruct 对象相同而不同;但在我的情况下,发生了什么对 (12, 16) 从映射返回值,但是当我动态地将它交换到对 (16, 12) 时,它返回 MyMap.end() 迭代(意味着未找到键),即使 Key(16 , 12) 存在于 MyMap 中
  • @user963167,当然,它们会有所不同。但是当我交换两个对象(live example)时,我认为没有问题。如果从最后一个 for 循环中删除 break 语句,您会看到输出不同 - 这意味着这些对象已再次交换。
  • @user963167 如果它返回 MyMap.end() 则 pair(16,12) 不在地图中,句号。您必须在其他地方有错误,在您未显示的代码中(除了您发布的代码中的错误,已经指出)。
  • for(const auto& p: m) Visual Studio 2010 抛出编译器错误“error C3531: 'p': a symbol which type contains 'auto' must have an initializer”
  • 基于范围的 for 是 C++11 功能。 MSVS 2010 不支持它。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-03-03
  • 2011-10-29
  • 2010-11-18
  • 1970-01-01
  • 2015-03-04
相关资源
最近更新 更多