用例:记录缓冲区。这是基本的想法。 使其工作要求当元素添加到地图时,记录结构的构造函数知道用作记录编号的键。 当然,这可以通过更多代码完成,但这对我来说看起来最优雅。 最小编码:
#include <whatever>
struct record
{
string foo;
record(unsigned irec) { foo=readrecord(irec); }
};
map<unsigned,record>recbuf;
int main()
{
// if the element is not yet in the map, it should be read.
string foo_ten=recbuf[10].foo;
// do something with the result
printf("foo_ten: %s\n",foo_ten.c_str());
return 0;
}
Edit1:上面的代码不起作用。 任何想法如何让这个工作? EDIT2: 我派生了一个mapplus类,添加了另一个map :: operator []:
template<class _Kty, class _Ty, class _Pr = less<_Kty>, class _Alloc = allocator<pair<const _Kty, _Ty> > >class mapplus :public map<_Kty, _Ty, _Pr, _Alloc>
{
public:
mapped_type& operator[](const _Kty &_Keyval)
{ // find element matching _Keyval or insert with default mapped
iterator _Where = _Mybase::lower_bound(_Keyval);
if (_Where == _Mybase::end()
|| _Mybase::_Getcomp()(_Keyval, _Mybase::_Key(_Where._Mynode())))
_Where = _Mybase::emplace_hint(_Where,
_Keyval,
_Ty(_Keyval));
return (_Where->second);
}
};
这确实有效。我仍然对向我指出的评论感兴趣,我以不必要的复杂等方式做到了这一点。我有吗?可以用更少的ado来完成吗?
答案 0 :(得分:0)
因此,您希望使用record
构造函数构建record(unsigned)
个对象,而不是默认构造函数。
很遗憾,operator[]
(reference)无法做到这一点:
如果k匹配容器中元素的键,则为函数 返回对其映射值的引用。
如果k与容器中任何元素的键不匹配,则 function使用该键插入一个新元素并返回一个引用 到它的映射值。请注意,这总是会增加容器 即使没有为元素分配映射值,也将大小加1 element是使用其默认构造函数构造的。
我不建议为operator[]
重载std::map
,对我而言,这似乎是一个糟糕的设计。
但是,您可以使用其他方法执行此操作,例如insert
或emplace
(C ++ 11)。
例如,请参阅此答案:Using std::map<K,V> where V has no usable default constructor
经过测试的例子:
#include <map>
#include <sstream>
#include <iostream>
std::string readRecord(int id)
{
std::stringstream stream;
stream << id;
return stream.str();
}
struct Record
{
Record(int id)
: foo(readRecord(id))
{
}
std::string foo;
};
int main()
{
std::map<int, Record> m;
for (int i = 0; i < 10; ++i)
m.insert(std::make_pair(i, Record(i)));
std::cout << m.at(5).foo << std::endl;
// std::cout << m[7].foo << std::endl; // error 'Record::Record': no appropriate default constructor available
return 0;
}