C++“error: passing 'const std::map<int, std::basic_string<char>>>' as 'this' argument of ...”意为:在某个函数中,将“const std::map<int,std::basic_string<char>>”作为“this”参数传递时出现错误。

19

以下是摘自代码的片段:

color.h:

class color {
public:
    color();

    enum colorType {
        black, blue, green, cyan, red,
        magenta, brown, lightgray, nocolor
    };

    colorType getColorType();
    void setColorType(colorType cColortype);

    string getColorText() const;

private:
    colorType cColortype = nocolor;
    map<int, string> colors = {
        {black, "black"},
        {blue, "blue"},
        {green, "green"},
        {cyan, "cyan"},
        {red, "red"},
        {magenta, "magenta"},
        {brown, "brown"},
        {lightgray, "lightgray"},
        {nocolor, "nocolor"}};
};

颜色.cpp:

color::color() {
}

color::colorType color::getColorType() {
    return cColortype;
}

void color::setColorType(colorType cColortype) {
    this->cColortype = cColortype;
}

string color::getColorText() const {
    return colors[cColortype];
}

我遇到了以下错误:

color.cpp:16:29: error: passing 'const std::map >' as 'this' argument of 'std::map<_Key, _Tp, _Compare, _Alloc>::mapped_type& std::map<_Key, _Tp, _Compare, _Alloc>::operator[](std::map<_Key, _Tp, _Compare, _Alloc>::key_type&&) [with _Key = int; _Tp = std::basic_string; _Compare = std::less; _Alloc = std::allocator > >; std::map<_Key, _Tp, _Compare, _Alloc>::mapped_type = std::basic_string; std::map<_Key, _Tp, _Compare, _Alloc>::key_type = int]' discards qualifiers [-fpermissive]

在 getColorText 中的 "return colors[cColortype];" 导致了这个错误。

这是一个课程项目,为了完成作业,我可以通过移除 getColorText 签名中的 const 声明使其工作,但我想学习/采用良好的做法并遵循对不修改数据的成员函数使用 const 的建议,所以我想知道如何解决这个问题。

我通常非常擅长调试和故障排除,但是这个错误消息太复杂了,几乎没有什么帮助。

感谢任何帮助。


我的第一个建议是在color::getColorText() const中使用std::map<>::find调用适当地删除下标运算符。 - nakiya
3个回答

46
string color::getColorText() const {
    return colors[cColortype];
}
问题在于您将函数标记为conststd::map上的operator[]被标记为非常量,不能在这样的常量函数中使用。 您需要手动使用std::map::find(或其他机制)搜索输入类型并处理未找到的情况。
如果您正在使用C ++ 11,则可以改用std::map::at,它允许在常量映射上使用,并在请求的元素不存在时引发异常。

1
std::map::at非常完美地符合要求。非常感谢。 - WXB13
是的,std::map :: at 是我实际需要的。 - Igal Alkon

5
关键在于最后几个字:"放弃限定符"。 getColorText 是一个 const 成员函数,所以 colorsconst 的。但是 map::operator[]() 不是 const 的。

2

首先:地图 map<int, string> colors 必须是从 cColorType 到字符串的映射,而不是从整数到字符串的映射:

map<cColorType, string> colors

第二点:正如一些人已经回答的那样:map::operator[]()不是const。原因是这个操作符返回了一个引用,允许你修改它的值。
我建议采用以下解决方案:您可以创建第二个私有属性:颜色字符串格式。因此您将有两个获取函数(每种颜色一个),和一个设置函数(它将修改两个颜色属性)。

实际上,cColorType是一个变量名而不是类型。也许你想说的是colorType。这其实并不必要,因为colorType是一个映射到int的枚举,所以"map<int, string> colors"签名可以正常工作。我在帖子中省略的代码部分是一个访问器,它以字符串作为参数,并对颜色执行反向映射查找,以获取相应的colorType。具有反向查找的映射消除了在2种不同格式中存储颜色设置的需要。 - WXB13
是的,你关于cColorType是正确的,我道歉。将映射的第一个条目保留为“int”将起作用,但将其设置为colorType更加灵活:想象一下,您(或其他人)将来会重写此代码,并且希望colorType不是枚举类型。这个编码器不必更改映射的声明。你如何执行“反向映射查找”?我迫不及待地想看看 :) - Brainless
反向映射查找:https://dev59.com/SW025IYBdhLWcg3w4Z-u#19829556 - WXB13
你的地图反向查找使用了线性复杂度的 find_if。如果你存储了两个不同的属性,那么两个 Get 函数将会在常数时间内执行。而且由于两种颜色类型之间的匹配是完美的,所以你不需要进行反向查找。相反,你可以编写两个代表彼此的反函数的映射。 - Brainless

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接