有一个widget类如下:
class Widget
{
public:
Widget();
Widget(double weight);
Widget& operator = (double weight);
}
使用如下:
std::map<int, Widget> datas; // 语句1
datas[1] = 1.50; // 语句2
调用语句2之前,datas为空。
因此,语句2等同于先默认构造一对象,然后再对其进行赋值。
auto iter = datas.insert({1, Widge()});
*(iter->second) = widget(1.50);
效率更高的做法是:直接使用1.50作为参数,在datas中进行构造。
datas.insert({1, widget(1.50)});
这样,一次构造函数调用代替了一次默认构造函数调用+1次拷贝赋值调用。
operator[]的设计目的是为了提供“添加和更新”的功能,当作为“添加”操作时,insert比operator[]效率更高。当作更新操作时,即当一个等价的键已经在map中时,却恰好相反。
datas[k] = v; // 使用operator [] 把k的值更新为v
typdef std::map<int, Widget> IntWidgetMap;
datas.insert(IntWidgetMap::value_type(k, v)).first->second = v; // 使用insert把k的值更新为v
非常明显,在更新数据时使用operator[]更加方便。
对效率的考虑使我们得出结论:当先map中添加元素时,要优先选用insert,而不是operator[]。
而从效率和美学的观点考虑,结论是:当更新已经在map中的元素的值时,要优先选择operator[]。