Using overloaded operator[] via an accessor functi

2019-09-16 22:22发布

我有一个返回常量引用类型(的std ::地图)的存取功能......

myMap_t const& getMap() const {return paramMap;} 

类型具有一个重载[]运算符。 什么是语法然后使用[]直接在类似下面的操作方式从吸气功能,但实际工作。

parameter = contextObj.getMap()[key];

错误信息:

context.cpp:35: error: passing   
  'const std::map<
     std::basic_string<char, std::char_traits<char>, std::allocator<char> >, 
     float, 
     std::less<std::basic_string<char, std::char_traits<char>, std::allocator<char> > >, 
     std::allocator<std::pair<
       const std::basic_string<char, std::char_traits<char>, std::allocator<char> >,
       float> > >'
as 'this' argument of 
  '_Tp& std::map<_Key, _Tp, _Compare, _Alloc>::operator[](const _Key&)  
with 
  _Key = std::basic_string<char, std::char_traits<char>, std::allocator<char> >,
  _Tp = float, 
  _Compare = std::less<std::basic_string<char, std::char_traits<char>,  td::allocator<char> > >, 
  _Alloc = std::allocator<std::pair<
    const std::basic_string<char, std::char_traits<char>, std::allocator<char> >, 
    float> >]' 
discards qualifiers

Answer 1:

问题是, operator[]在地图是不同诱变操作,你不能把它在一个const参照地图。 它是变异的原因是,它必须返回一个参考值,并认为,如果该键在容器中是不存在的,它会插入该密钥解决的新的默认构造值和参考回到它。

如果你有一个const引用,并要确定一个元素是否存在(或访问),您必须使用std::map<>::find ,将返回一个迭代。 如果该元素不存在,则迭代器的值将被m.end()



Answer 2:

您返回std::map通过const引用,但std::map::operator[]是不是一个const函数,因为有时它需要改变地图。
为了解决这个问题,你应该做下列之一:
(A)使用.find代替[]

auto iter = contextObj.getMap().find( key );
if (iter != contextObj.getMap().end())
    param = iter->second;

(B)返回图作为非const的(不推荐)
(C)做一个包装类(不值得的大部分时间)



Answer 3:

你返回一个const myMap_t&从你的方法getMap() 从你的错误信息myMap_t是一个一个typedef std::map 。 疗法operator[]std::map需要修改的对象(不能叫上常量),因为它可以将项目插入地图(如果与指定的键不存在,那么将插入一个地图,然后返回一个参考的一个)。 为了解决这个问题,你有两个选择:

  • 使用contextObj.getMap().find(key) ,而不是contextObj.getMap()[key]来获得一个迭代的元素(或map.end()如果不存在的话)
  • 返回myMap_t&没有常量),以获得在其上修改的对象operator[]可以被称为


Answer 4:

context.cpp:35: error: passing   
  'const std::map<
     std::basic_string<char, std::char_traits<char>, std::allocator<char> >, 
     float, 
     std::less<std::basic_string<char, std::char_traits<char>, std::allocator<char> > >, 
     std::allocator<std::pair<
       const std::basic_string<char, std::char_traits<char>, std::allocator<char> >,
       float> > >'
as 'this' argument of 
  '_Tp& std::map<_Key, _Tp, _Compare, _Alloc>::operator[](const _Key&)  
with 
  _Key = std::basic_string<char, std::char_traits<char>, std::allocator<char> >,
  _Tp = float, 
  _Compare = std::less<std::basic_string<char, std::char_traits<char>,  td::allocator<char> > >, 
  _Alloc = std::allocator<std::pair<
    const std::basic_string<char, std::char_traits<char>, std::allocator<char> >, 
    float> >' 
discards qualifiers

std::basic_string是用来实现模板std::string ,而事实上std::string是仅仅基于实例char 。 所以替代,在第一:

context.cpp:35: error: passing   
  'const std::map<
     std::string, 
     float, 
     std::less<std::string>, 
     std::allocator<std::pair<const std::string, float> >
  >'
as 'this' argument of 
  '_Tp& std::map<_Key, _Tp, _Compare, _Alloc>::operator[](const _Key&)  
with 
  _Key = std::string,
  _Tp = float, 
  _Compare = std::less<std::string>, 
  _Alloc = std::allocator<std::pair<const std::string> >' 
discards qualifiers

我们真的不关心_Compare (比较函数)和_Alloc (分配器)参数为我们的地图,因为我们只是使用默认值; 所以让我们忽略这些,让我们也代替_Key_Tp值到模板描述:

context.cpp:35: error: passing   
  'const std::map<std::string, float>'
as 'this' argument of 
  'float& std::map<std::string, float>::operator[](const std::string&)  
discards qualifiers

我们去那里,要简单得多。 我们正在使用的operator[]我们std::map<std::string, float> ,我们正在尝试使用它的const std::map<std::string, float> (即,这是我们使用的是什么this说法呼叫)。 这种“丢弃预选赛”,具体而言, const限定符。

编译器告诉你的是, operator[]的地图不答应保守地图const ,即允许其改变地图。 这是一个编译器错误,因为代码与内置的断言,即地图不会改变写入。

为什么会在地图的变化? 好了,看的文档:

如果x在容器中的元件的密钥相匹配,则该函数返回到其映射值的引用。

如果x不在该容器匹配任何元素的键,功能插入一个新元素与该键并返回到它的映射值的引用。 请注意,这都是以一增大了地图的大小,即使没有映射的值被分配给元素(该元素是使用其默认的构造构造的)。

(重点煤矿)。

插入元件是肯定的变形例。

它为什么要这样做呢? 好了, 我们已经有一个问题 。



文章来源: Using overloaded operator[] via an accessor function