使用[]时,为什么C++ map类型参数需要空构造函数?

Nic*_*ton 88 c++ dictionary

另请参见 C++标准列表和默认构造类型

不是一个主要问题,只是烦人,因为我不希望我的类在没有特定参数的情况下被实例化.

#include <map>

struct MyClass
{
    MyClass(int t);
};

int main() {
    std::map<int, MyClass> myMap;
    myMap[14] = MyClass(42);
}
Run Code Online (Sandbox Code Playgroud)

这给了我以下g ++错误:

/usr/include/c++/4.3/bits/stl_map.h:419:错误:没有用于调用'MyClass()'的匹配函数

如果我添加一个默认构造函数,这编译很好; 我确信它不是由不正确的语法引起的.

bay*_*yda 153

运算符[]附带此问题.从SGI文档引用:

data_type& operator[](const key_type& k) - 返回对与特定键关联的对象的引用.如果地图尚未包含此类对象,请operator[] 插入默认对象 data_type().

如果您没有默认构造函数,则可以使用insert/find函数.以下示例正常工作:

myMap.insert( std::map< int, MyClass >::value_type ( 1, MyClass(1) ) );
myMap.find( 1 )->second;
Run Code Online (Sandbox Code Playgroud)

  • 优秀的答案 - 请注意C++ 11中的`emplace`作为`insert`的简洁替代. (10认同)
  • 为什么在`insert`调用中存在`std :: &lt;map&gt; :: value_type`? (2认同)

Ass*_*vie 6

是.STL容器中的值需要维护复制语义.IOW,它们需要表现得像原始类型(例如int),这意味着,除其他外,它们应该是默认构造的.

如果没有这个(以及其他要求),在实现STL容器的数据结构上实现各种内部复制/移动/交换/比较操作将是不必要的.

在参考C++标准时,我看到我的答案不准确.事实上,默认构造不是必需的:

从20.1.4.1开始:

默认构造函数不是必需的.某些容器类成员函数签名将默认构造函数指定为默认参数.T()必须是明确定义的表达式......

因此,严格来说,如果您恰好使用在其签名中使用默认构造函数的容器函数,则您的值类型只需要是默认构造的.

存储在STL容器中的所有值的实际要求(23.1.3)是CopyConstructibleAssignable.

对于特定容器也存在其他特定要求,例如Comparable(例如,用于地图中的键).


顺便说一句,下面对没有错误编译科莫:

#include <map>

class MyClass
{
public:
    MyClass(int t);
};

int main()
{
    std::map<int, MyClass> myMap;
}
Run Code Online (Sandbox Code Playgroud)

所以这可能是一个g ++问题.

  • 该代码可能会编译,因为您没有调用myMap [] (11认同)
  • 你认为bb可以关于[]运算符吗? (2认同)

oo_*_*_oo 5

检查 stl::map 的存储类型的要求。许多 stl 集合要求存储类型包含一些特定的属性(默认构造函数、复制构造函数等)。

stl::map 需要不带参数的构造函数,因为当使用键调用 operator[] 时会使用它,该键尚未被映射保留。在这种情况下,operator[] 插入由使用无参数构造函数构造的新键和值组成的新条目。然后返回这个新值。