从运算符[]返回对映射的char*的引用

returning a reference to mapped char* from operator[]

本文关键字:char 引用 映射 运算符 返回      更新时间:2023-10-16

我有一个数据结构:

#include <map>
struct array{
map<const char*, char*> data;   
//constructor
array(const char* key, char* value = ""){
data.insert(pair<const char*, char*>(key, value));  
}   
//overloaded operator[] seems to be my problem
char* operator[](const char* key) { return (char*)data[key]; }
};

现在,在没有使分配operator=过载的情况下,我进行了试驾它是这样的:

array var("first", "second");
var["third"] = "fourth";          //and my compiler (gcc) is angry about this

现在,我的编译器返回了以下错误:

函数.cpp:13:18:error:赋值的左操作数需要左值

问题:我有什么不明白的地方吗?我该怎么办从CCD_ 3返回CCD_,以便CCD_ 4正常工作?请注意,我不想用c++的字符串类型来做这件事。严格地说是CCD_ 5。

我有什么不明白的地方吗?

您正在按值返回指针。这意味着调用者将收到指针的副本。调用方不能使用映射中指针的副本来更改映射中的指针。

如何从运算符[]返回map::data["key"]的地址,使var["third"]="fourth";工作正常吗?

返回对它的引用:

char*& operator[](const char* key) { /* ... */ }

为了做到这一点,你需要去掉多余的演员阵容:

return data[key];

程序中的另一个问题是,您在映射中存储了非常量char*,但您用字符串文字初始化了这些指针,即const。这种转换在c++11中是非法的,这意味着你的程序格式不正确。甚至在c++11之前,由于标准c++已经存在,这种转换就已经被弃用了。

这样做的危险在于,您可能会意外地通过非常量指针修改常量字符串,这将导致未定义的行为。

解决方案:如果不需要修改字符串内容,请在映射中使用const char*指针。如果需要修改,则改为指向从字符串文字中复制的单独分配的char数组。实现后者的最简单方法是使用std::string作为值类型,但如果您不想这样做,那么您可以自己管理数组。


程序中的第三个问题是,您似乎认为var["third"]可以保证找到用"third"初始化的密钥。这种假设是错误的。单独但相同的字符串文字不能保证具有相同的地址。

解决方案:使用std::string作为键,或者使用自定义的比较函数,根据字符串的内容对其进行比较。提示:使用std::strcmp来实现函数。


p.S.您似乎没有operator[](...)的任何过载,因此它不是">过载"。

我有什么不明白的地方吗?

是的,我认为您对代码及其意图感到困惑。严格来说,答案是你试图在一个只允许使用lvalues的地方使用rvalue,即在赋值的lhs上。为了解决这个直接的问题,你需要将你的运营商更改为:

char*& operator[](const char* key) { return data[key]; }

(即返回对包含在映射中的指针的引用)。这会编译,但我不认为这个结构会做你想做的事。例如,修改地图条目的内容字符串如下:

var["third"][0] = 'a';

如果您使用字符串文字来填充它,这将是未定义的行为,就像您在示例中所做的那样。

最好听从评论者的建议,改用std::strings

要使其编译,您必须将运算符[]签名更改为:

char*& operator[](const char* key) { return data[key]; }

但随后您将得到警告和可能的UB,因为字符串文字是常量数组,而您希望将其分配给非常量char*。要使这些警告静音,您必须进行额外的更改,所有map::data["key"]0到const char*:

struct array{
std::map<const char*, const char*> data;   
//constructor
array(const char* key, const char* value = ""){
data.insert(std::pair<const char*, const char*>(key, value));  
}   
//overloaded operator[] seems to be my problem
const char*& operator[](const char* key) { return data[key]; }
};

但也许这不是你想要的。

最好的解决方案是将std::map<const char*, char*>转换为std::map<std::string, std::string>

相关文章: