用例:记录缓冲区。这是基本的想法。 使其工作需要 record 结构的构造函数知道在将元素添加到映射时用作 recordnumber 的键。 当然,这可以用更多的代码来完成,但这对我来说看起来最优雅。 最少编码:
#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:上面的代码将不起作用。 任何想法如何让它工作? 编辑2: 我派生了一个 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);
}
};
这确实有效。我仍然对向我指出我以不必要的复杂等方式完成此操作的评论感兴趣。我有吗?可以事半功倍吗?
最佳答案
因此,您希望使用 record(unsigned)
构造函数而不是默认构造函数构造 record
对象。
不幸的是,没有办法用 operator[]
( reference ) 来做到这一点:
If k matches the key of an element in the container, the function returns a reference to its mapped value.
If k does not match the key of any element in the container, the function inserts a new element with that key and returns a reference to its mapped value. Notice that this always increases the container size by one, even if no mapped value is assigned to the element (the element is constructed using its default constructor).
我不建议为 std::map
重载 operator[]
,对我来说这似乎是一个糟糕的设计。
但是,您可以使用其他方法来实现,例如 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;
}
关于c++ - 映射中结构的构造函数中的访问键,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37785405/