我有一个数据结构:
#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
现在,我的编译器返回以下错误:
问题:有什么不明白的吗?我怎么能够
从
map::data["key"]
返回operator[]
的地址,以便
var["third"] = "fourth";
正常工作?提醒您,我不想使用c++的字符串类型执行此操作。严格char*
。 最佳答案
您正在按值返回指针。这意味着调用者将收到指针的副本。调用者无法使用 map 中指针的副本来更改 map 中的指针。
返回对其的引用:
char*& operator[](const char* key) { /* ... */ }
为了使它起作用,您需要摆脱多余的 Actor 表:
return data[key];
程序中的另一个问题是,您在 map 中存储了非常量
char*
,但是使用字符串文字const
初始化了这些指针。这种转换在c++ 11中是非法的,这意味着您的程序格式错误。甚至在c++ 11之前,由于已经存在标准c++,因此不赞成使用这种转换。这样做的危险是您可能会通过非const指针意外修改const字符串,这将导致未定义的行为。
解决方案:如果不需要修改字符串内容,则在映射中使用
const char*
指针。如果需要修改,则指向从字符串文字中复制的单独分配的char
数组。实现后者的最简单方法是使用std::string
作为值类型,但是如果您不想这样做,则可以自己管理数组。程序中的第三个问题是您似乎假设
var["third"]
可以保证找到已使用"third"
初始化的键。这个假设是错误的。不能保证单独的但相同的字符串文字具有相同的地址。解决方案:使用
std::string
作为键,或者使用定制的比较函子,根据其内容对字符串进行比较。提示:使用std::strcmp
来实现函子。附言您似乎没有对
operator[](...)
重载,因此它不是“重载”的。