如何在另一个std::pair中插入一对std::pair?

10

我声明了一个从字符串映射到一对成对的map,如下所示:

std::map<std::wstring, 
         std::pair<std::pair<long, long>, 
                   std::pair<long, long>>> reference;

我将其初始化为:

reference.insert(L"First", 
                 std::pair<std::pair<long, long>, 
                           std::pair<long, long>>(std::pair<long, long>(-1, -1),
                           std::pair<long, long>(0, 0)));

然而,Visual C++ 给我报了一个错误 "C2664,没有可接受该源类型的构造函数,或者构造函数重载解析不明确"。

我刚开始使用模板和STL,无法确定自己错在哪里。


4
请使用typedef和std::make_pair使其易于阅读。 - GManNickG
我重新格式化了它,使得它对眼睛来说更加友好一些。 - egrunin
你可以改用 std::tr1::tuple,这样就不需要嵌套所有的 std::pair 了。Boost 也有一个 tuple 实现。 - Praetorian
嘿,你好啊。我听说你喜欢使用 std::pair,所以我在你的…… - Robben_Ford_Fan_boy
据我所知,不是所有的供应商都实现了元组。在转向 Boost 之前,我正在尝试先学习 STL。 - Fábio
5个回答

17
>>>无法被正确解析(除非你有一个C++0x编译器)。 将其改为> > >
这样做:
reference.insert("First",

应该是:

reference.insert(L"First",
                ^^^

此外,还有一个实用函数可以更轻松地构建键值对:

std::pair<std::pair<long, long>, std::pair<long, long>>(std::pair<long, long>(-1, -1), std::pair<long, long>(0, 0))

可以是:

std::make_pair(std::make_pair(-1L,-1L),std::make_pair(0L,0L))

试试这个:

reference[L"First"]
    = std::make_pair(std::make_pair(-1L,-1L),std::make_pair(0L,0L));

感谢您的帮助。我编辑了我的问题,添加了 L"" 到我的 wstring 中,使问题更容易“解析”。 - Fábio
1
一个比我的更好的答案,但请注意,使用 reference[key] = value 插入可能会与 reference.insert(make_pair(key,value)) 给出不同的行为;使用 [] 会覆盖现有元素,而 insert 不会。 - Mike Seymour

2

map::insert 函数需要一个 std::pair 参数,而不是两个参数。使用 std::make_pair 可以让代码更简洁(它会从函数参数中推断模板参数),例如:

reference.insert(std::make_pair("First", 
                                std::make_pair(std::make_pair(-1L,-1L),
                                               std::make_pair(0L,0L))));

2

在关闭模板时,C++ 会因连续的 ">" 而混淆,因为它将其解释为移位运算符。

在关闭模板之间添加空格,将 >>> 改为 > > >。


0

在调试这种情况时,使用typedef有助于解决问题。

// test1.cpp : Defines the entry point for the console application.
//

#include "stdafx.h"

#include <map>
#include <string>

int _tmain(int argc, _TCHAR* argv[])
{
    typedef std::pair<long, long> ElementType;
    typedef std::pair<ElementType, ElementType> ValueType;
    typedef std::wstring KeyType;
    std::map<KeyType, ValueType> reference;

    KeyType key = L"First";
    reference[key] = ValueType(ElementType(-1, -1), ElementType(0, 0));

    return 0;
}

即使你 #include <string> ,也没有 OP 尝试使用的 insert() 函数。你发布的示例代码确实有效且易读,但是这是因为你替换了 insert() 而不是因为该 include 的缘故,正如你所说的那样。 - sth
如果你删掉“你只需要<string>”这部分,我认为有点误导,但是我认为它确实有帮助,我会点赞的。 - sth
好的,你明白了。我不知道你是否意识到你在回答中写了“operator[]用于插入会使代码更易读”。正如你所说,insert操作并不存在! - ttt
是的,我意识到了,我在发布我的答案后看到了你的答案,然后想到“谁会对此进行投票,operator[]才是正确的方法!”然后我被<string>的东西搞糊涂了,于是去尝试一下是否确实缺少wstring(const char*)之类的构造函数会像问题中那样产生错误消息。然而,我无法重现任何类似的情况,所以我决定发表评论。(+1) - sth

0
你可以通过创建一个辅助函数来简化你的代码,以创建一对对的对,类似于标准库中可用的std::make_pair辅助函数。此外,使用映射的operator[]进行插入会导致更易于阅读的代码:
template<typename T, typename U, typename V, typename W>
std::pair< std::pair<T,U>, std::pair<V,W> > make_pair_pair(T t, U u, V v, W w) {
   // using std::make_pair instead of the constructor for better readability
   return std::make_pair(std::make_pair(t, u), std::make_pair(v, w));
}

reference[L"First"] = make_pair_pair(1,2,3,4);

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接