如何解决C++ 映射条目作为参考
基本上我有一个包含一些条目的地图。我使用自定义构造函数创建条目并删除默认构造函数。在一个条目中,我想更新一个值。这是我想通过引用条目然后调用更新/设置方法来实现的。
我有以下代码:
#include <map>
#include <string>
class CacheEntry
{
public:
CacheEntry() = delete;
CacheEntry(const int value1)
: value1(value1)
{
}
void SetValue2(const int value2)
{
this->value2 = value2;
}
private:
const int value1;
int value2;
};
class Cache
{
public:
void SetValue2(const std::string& name,const int value2)
{
if (entries.count(name) == 0)
{
return;
}
CacheEntry& entry = entries[name];
entry.SetValue2(value2);
}
private:
std::map<std::string,CacheEntry> entries;
};
编译时出现如下错误:
In file included from /usr/include/c++/9/bits/stl_map.h:63,from /usr/include/c++/9/map:61,from test.cpp:1:
/usr/include/c++/9/tuple: In instantiation of ‘std::pair<_T1,_T2>::pair(std::tuple<_Args1 ...>&,std::tuple<_Args2 ...>&,std::_Index_tuple<_Indexes1 ...>,std::_Index_tuple<_Indexes2 ...>) [with _Args1 = {const std::__cxx11::basic_string<char,std::char_traits<char>,std::allocator<char> >&}; long unsigned int ..._Indexes1 = {0}; _Args2 = {}; long unsigned int ..._Indexes2 = {}; _T1 = const std::__cxx11::basic_string<char>; _T2 = CacheEntry]’:
/usr/include/c++/9/tuple:1663:63: required from ‘std::pair<_T1,_T2>::pair(std::piecewise_construct_t,std::tuple<_Args1 ...>,std::tuple<_Args2 ...>) [with _Args1 = {const std::__cxx11::basic_string<char,std::allocator<char> >&}; _Args2 = {}; _T1 = const std::__cxx11::basic_string<char>; _T2 = CacheEntry]’
/usr/include/c++/9/ext/new_allocator.h:147:4: required from ‘void __gnu_cxx::new_allocator<_Tp>::construct(_Up*,_Args&& ...) [with _Up = std::pair<const std::__cxx11::basic_string<char>,CacheEntry>; _Args = {const std::piecewise_construct_t&,std::tuple<const std::__cxx11::basic_string<char,std::allocator<char> >&>,std::tuple<>}; _Tp = std::_Rb_tree_node<std::pair<const std::__cxx11::basic_string<char>,CacheEntry> >]’
/usr/include/c++/9/bits/alloc_traits.h:484:4: required from ‘static void std::allocator_traits<std::allocator<_Tp1> >::construct(std::allocator_traits<std::allocator<_Tp1> >::allocator_type&,_Up*,CacheEntry> >; std::allocator_traits<std::allocator<_Tp1> >::allocator_type = std::allocator<std::_Rb_tree_node<std::pair<const std::__cxx11::basic_string<char>,CacheEntry> > >]’
/usr/include/c++/9/bits/stl_tree.h:614:32: required from ‘void std::_Rb_tree<_Key,_Val,_KeyOfValue,_Compare,_Alloc>::_M_construct_node(std::_Rb_tree<_Key,_Alloc>::_Link_type,_Args&& ...) [with _Args = {const std::piecewise_construct_t&,std::tuple<>}; _Key = std::__cxx11::basic_string<char>; _Val = std::pair<const std::__cxx11::basic_string<char>,CacheEntry>; _KeyOfValue = std::_Select1st<std::pair<const std::__cxx11::basic_string<char>,CacheEntry> >; _Compare = std::less<std::__cxx11::basic_string<char> >; _Alloc = std::allocator<std::pair<const std::__cxx11::basic_string<char>,CacheEntry> >; std::_Rb_tree<_Key,_Alloc>::_Link_type = std::_Rb_tree_node<std::pair<const std::__cxx11::basic_string<char>,CacheEntry> >*]’
/usr/include/c++/9/bits/stl_tree.h:631:4: required from ‘std::_Rb_tree_node<_Val>* std::_Rb_tree<_Key,_Alloc>::_M_create_node(_Args&& ...) [with _Args = {const std::piecewise_construct_t&,CacheEntry> >*]’
/usr/include/c++/9/bits/stl_tree.h:2455:13: required from ‘std::_Rb_tree<_Key,_Alloc>::iterator std::_Rb_tree<_Key,_Alloc>::_M_emplace_hint_unique(std::_Rb_tree<_Key,_Alloc>::const_iterator,_Alloc>::iterator = std::_Rb_tree_iterator<std::pair<const std::__cxx11::basic_string<char>,_Alloc>::const_iterator = std::_Rb_tree_const_iterator<std::pair<const std::__cxx11::basic_string<char>,CacheEntry> >]’
/usr/include/c++/9/bits/stl_map.h:499:8: required from ‘std::map<_Key,_Tp,_Alloc>::mapped_type& std::map<_Key,_Alloc>::operator[](const key_type&) [with _Key = std::__cxx11::basic_string<char>; _Tp = CacheEntry; _Compare = std::less<std::__cxx11::basic_string<char> >; _Alloc = std::allocator<std::pair<const std::__cxx11::basic_string<char>,CacheEntry> >; std::map<_Key,_Alloc>::mapped_type = CacheEntry; std::map<_Key,_Alloc>::key_type = std::__cxx11::basic_string<char>]’
test.cpp:33:36: required from here
/usr/include/c++/9/tuple:1674:70: error: use of deleted function ‘CacheEntry::CacheEntry()’
1674 | second(std::forward<_Args2>(std::get<_Indexes2>(__tuple2))...)
| ^
test.cpp:7:3: note: declared here
7 | CacheEntry() = delete;
| ^~~~~~~~~~
为什么编译器会在 CacheEntry& entry = entries[name];
处创建一个新对象?我希望引用地图中已经存在的对象。
我知道我可以删除 CacheEntry() = delete;
,但这不是我想要的。
解决方法
为什么编译器会在 CacheEntry& entry = entries[name];
处创建一个新对象?
map::operator[]
会创建一个新的 default-constructed 条目。即使您使用 map::count()
来确保不会实际创建新条目,operator[]
后面的实现代码仍然必须正确编译。这意味着如果您想使用 operator[]
,map
的条目必须具有有效的默认构造函数。
否则,根本不要使用operator[]
,而是使用map::find()
,例如:
void SetValue2(const std::string& name,const int value2)
{
auto iter = entries.find(name);
if (iter != entries.end())
iter->second.SetValue2(value2);
}
我希望引用地图中已经存在的对象。
正确 - 在运行时。但是在编译时,编译器无法知道某个对象是否已经存在。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。