简体   繁体   English

C++ 映射访问丢弃限定符 (const)

[英]C++ map access discards qualifiers (const)

The following code says that passing the map as const into the operator[] method discards qualifiers:以下代码表示将映射作为const传递到operator[]方法会丢弃限定符:

#include <iostream>
#include <map>
#include <string>

using namespace std;

class MapWrapper {
public:
    const int &get_value(const int &key) const {
        return _map[key];
    }

private:
    map<int, int> _map;
};

int main() {
    MapWrapper mw;
    cout << mw.get_value(42) << endl;
    return 0;
}

Is this because of the possible allocation that occurs on the map access?这是因为地图访问时可能发生的分配吗? Can no functions with map accesses be declared const?不能将具有映射访问的函数声明为 const 吗?

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

std::map 's operator [] is not declared as const , and cannot be due to its behavior: std::mapoperator []未声明为const ,并且不能由于其行为:

T& operator[] (const Key& key) T& operator[] (const Key& key)

Returns a reference to the value that is mapped to a key equivalent to key, performing insertion if such key does not already exist.返回对映射到与 key 等效的键的值的引用,如果此类键不存在,则执行插入。

As a result, your function cannot be declared const , and use the map's operator[] .因此,您的函数不能声明为const ,也不能使用映射的operator[]

std::map 's find() function allows you to look up a key without modifying the map. std::mapfind()函数允许您在不修改映射的情况下查找键。

find() returns an iterator , or const_iterator to an std::pair containing both the key ( .first ) and the value ( .second ). find()返回一个iterator ,或const_iteratorstd::pair同时含有键( .first )和值( .second )。

In C++11, you could also use at() for std::map .在 C++11 中,您还可以将at()用于std::map If element doesn't exist the function throws a std::out_of_range exception, in contrast to operator [] .如果元素不存在,该函数会抛出std::out_of_range异常,与operator []

Since operator[] does not have a const-qualified overload, it cannot be safely used in a const-qualified function.由于operator[]没有 const 限定的重载,因此不能安全地用于 const 限定的函数中。 This is probably because the current overload was built with the goal of both returning and setting key values.这可能是因为当前的重载是为了返回和设置键值而构建的。

Instead, you can use:相反,您可以使用:

VALUE = map.find(KEY)->second;

or, in C++11, you can use the at() operator:或者,在 C++11 中,您可以使用at()运算符:

VALUE = map.at(KEY);

You cannot use operator[] on a map that is const as that method is not const as it allows you to modify the map (you can assign to _map[key] ).您不能在const映射上使用operator[] ,因为该方法不是const因为它允许您修改映射(您可以分配给_map[key] )。 Try using the find method instead.尝试改用find方法。

Some newer versions of the GCC headers (4.1 and 4.2 on my machine) have non-standard member functions map::at() which are declared const and throw std::out_of_range if the key is not in the map.一些较新版本的 GCC 标头(我的机器上为 4.1 和 4.2)具有非标准成员函数 map::at(),它们被声明为 const 并在键不在映射中时抛出 std::out_of_range 。

const mapped_type& at(const key_type& __k) const

From a reference in the function's comment, it appears that this has been suggested as a new member function in the standard library.从函数注释中的引用来看,这似乎已被建议作为标准库中的新成员函数。

First, you should not be using symbols beginning with _ because they are reserved to the language implementation/compiler writer.首先,您不应该使用以 _ 开头的符号,因为它们是为语言实现/编译器编写者保留的。 It would be very easy for _map to be a syntax error on someone's compiler, and you would have no one to blame but yourself. _map 很容易成为某人编译器上的语法错误,除了你自己之外,没有人可以责怪。

If you want to use an underscore, put it at the end, not the beginning.如果要使用下划线,请将其放在末尾,而不是开头。 You probably made this mistake because you saw some Microsoft code doing it.您可能犯了这个错误,因为您看到一些 Microsoft 代码这样做。 Remember, they write their own compiler, so they may be able to get away with it.请记住,他们编写自己的编译器,因此他们可能能够逃脱。 Even so, it's a bad idea.即便如此,这也是一个坏主意。

the operator [] not only returns a reference, it actually creates the entry in the map.运算符 [] 不仅返回一个引用,它实际上在映射中创建了条目。 So you aren't just getting a mapping, if there is none, you are creating one.所以你不只是得到一个映射,如果没有,你正在创建一个。 That's not what you intended.那不是你想要的。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 C ++丢弃限定符 - C++ discards qualifiers 错误传递 const 作为丢弃限定符 C++ 的这个参数 - error passing const as this argument of discards qualifiers C++ c ++ QVector / Vector问题... const ...丢弃限定符 - c++ QVector/Vector issues… const… discards qualifiers QT&C ++:传递&#39;const QString&#39;会丢弃限定词 - QT & C++ : Passing 'const QString' discards qualifiers C ++:将const作为&#39;this&#39;参数传递...丢弃涉及Json的限定符 - C++: passing const as 'this' argument … discards qualifiers involving Json C ++中虚函数和/或const的“丢弃限定符”错误 - “Discards qualifiers” error with virtual function and/or const in c++ C++ 错误:传递&#39;const umap_int {aka const std::unordered_map<int, int> }&#39; 作为 &#39;this&#39; 参数丢弃限定符 [-fpermissive] - C++ error: passing ‘const umap_int {aka const std::unordered_map<int, int>}’ as ‘this’ argument discards qualifiers [-fpermissive] const字符串丢弃限定符 - const string discards qualifiers 奇怪的C ++错误:test.cpp:15:错误:将'const *'作为'*'的'this'参数传递丢弃限定符 - An odd C++ error: test.cpp:15: error: passing ‘const *’ as ‘this’ argument of ‘*’ discards qualifiers C ++ Boost-序列化错误-将&#39;const B&#39;作为&#39;this&#39;参数传递会丢弃限定符 - C++ Boost - serialization error - passing ‘const B’ as ‘this’ argument discards qualifiers
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM