【问题标题】:Type requirements for std::mapstd::map 的类型要求
【发布时间】:2011-05-14 09:13:48
【问题描述】:

今天我创建了一个映射,其中值类型没有默认构造函数。我很惊讶我无法使用 operator[] 将元素插入到此地图中,但我必须使用 insert 方法。

那么,std::map 的键值类型到底有什么要求呢?

这是一个简短的例子:

#include <map>

struct A
{
    A(int){}
};

int main()
{
    std::map< int, A > m;
    A a1(2);
    A a2(3);
    A a3(4);
    m[5] = a1;
    m[3] = a2;
    m[2] = a3;
}

我是这样编译的:

[vladimir@sandbox tmp]$ g++ b5.cpp -Wall -Wextra -ansi -pedantic
/usr/lib/gcc/i386-redhat-linux/4.3.0/../../../../include/c++/4.3.0/bits/stl_map.h: In member function ‘_Tp& std::map<_Key, _Tp, _Compare, _Alloc>::operator[](const _Key&) [with _Key = int, _Tp = A, _Compare = std::less<int>, _Alloc = std::allocator<std::pair<const int, A> >]’:
b5.cpp:14:   instantiated from here
/usr/lib/gcc/i386-redhat-linux/4.3.0/../../../../include/c++/4.3.0/bits/stl_map.h:419: error: no matching function for call to ‘A::A()’
b5.cpp:5: note: candidates are: A::A(int)
b5.cpp:4: note:                 A::A(const A&)

【问题讨论】:

    标签: c++ stl language-lawyer


    【解决方案1】:

    operator[] 确实需要默认可构造性,因为此方法的语义要求如果密钥尚不存在,则创建适当的条目。因此:

    map<TKey, TValue> mymap;
    TKey foo = …;
    TValue& x = mymap[foo];
    

    如果地图中不存在foo,将创建并存储一个新对象TValue(),并返回对它的引用。

    【讨论】:

      【解决方案2】:

      这个网站是一个很好的 STL 参考:http://www.sgi.com/tech/stl/

      基本上,它表示 map 具有强制的 2 个类型参数,KeyData。正如丹尼尔所说,Data 必须是 Assignable。然而,Key 被声明需要是可以与Compare 类型一起使用的类型,即Compare 指定一个函数对象,其参数类型为Key。在这种情况下,默认的Compare 函数对象是std::less&lt;T&gt;,这是一个Strict Weak Ordering,它使用operator&lt; 比较T 类型的对象。因此,如果您不更改Compare 类型,即使用默认值,std::less&lt;T&gt; 将与Key 类型一起使用,因此operator&lt; 将与Key 类型一起使用,因此Key 需要与operator&lt;相媲美。

      希望对您有所帮助!我知道这有点无缘无故,我并不是要居高临下,但我只是想确保绝对清楚如何对此进行推理。

      【讨论】:

      • 原则上这是一个很好的答案,但它不能解释为什么 OP 的代码失败了。
      • @Konrad 啊,但那是因为我在他发布错误消息之前回答了它。他当时发布的只是它不起作用。
      猜你喜欢
      • 1970-01-01
      • 2023-03-20
      • 1970-01-01
      • 1970-01-01
      • 2015-06-20
      • 1970-01-01
      • 2011-12-20
      • 1970-01-01
      • 2011-04-02
      相关资源
      最近更新 更多