为什么在使用时C ++映射types参数需要一个空的构造函数?

另请参阅C ++标准列表和缺省构造types

不是一个主要的问题,只是烦恼,因为我不希望我的课没有特定的参数实例化。

class MyClass { public: MyClass(MyType1 t); MyType2 &operator[](int index); } map<int, MyClass> myMap; 

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

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

这编译罚款,如果我添加一个默认的构造函数; 我确定它不是由不正确的语法造成的。

这个问题来自运算符[]。 SGI文档引用:

data_type& operator[](const key_type& k) – 返回与特定键关联的对象的引用。 如果地图尚未包含这样的对象,则operator[]将插入默认对象data_type()

如果你没有默认的构造函数,你可以使用插入/查找function。 以下示例工作正常:

 myMap.insert( std::map< int, MyClass >::value_type ( 1, MyClass(1) ) ); myMap.find( 1 )->second; 

是。 STL容器中的值需要保持复制语义。 IOW,他们需要像原始types(例如int),这意味着,除其他外,它们应该是默认可构造的。

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

参照C ++标准,我看到我的答案不准确。 事实上,默认构build并不是一个要求

从20.1.4.1:

默认的构造函数不是必需的。 某些容器类成员函数签名指定默认构造函数作为默认参数。 T()必须是一个明确的expression式…

所以,严格来说,如果碰巧使用在其签名中使用默认构造函数的容器的函数,则只需要将值types设置为默认构造。

存储在STL容器中的所有值的真实需求(23.1.3)是CopyConstructibleAssignable

对于特定的容器也有其他特定的要求,例如Comparable (例如对于地图中的键)。


顺便提一下,下面的代码在编译时没有错误:

 #include <map> class MyClass { public: MyClass(int t); }; int main() { std::map<int, MyClass> myMap; } 

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

检查stl :: map存储types的要求。 许多STL集合要求存储types包含一些特定的属性(默认构造函数,拷贝构造函数等)。

不带参数的构造函数是stl :: map所需要的,因为在调用operator []时,使用了map中尚未保存的key。 在这种情况下,operator []插入由无参数构造函数构造的新键和值。 然后这个新的价值被返回。

检查是否:

  • 你忘了';' 课后申报。
  • MyType应该已经被相应地声明了。
  • 那里没有默认的构造函数…

std :: map声明似乎是正确的,我想。

很可能是因为std :: pair需要它。 std :: pair使用值语义保存两个值,所以你需要能够实例化他们没有参数。 因此,代码在不同的地方使用std :: pair将映射值返回给调用者,这通常是通过实例化一个空对并在返回本地对之前将值分配给调用者来完成的。

你可以用智能指针来解决这个问题,使用map <int,smartptr <MyClass>>,但是增加了检查空指针的开销。