我想做一个包装std :: map的类,并检查以确保这些键是已批准的有效字符串的一个,并且还初始化了映射所有批准的有效字符串的默认值。我有问题让下标操作工作,特别是它的常量版本。用std :: map成员变量的类的下标运算符
这里是我的类原型代码:
#include <set>
#include <string>
#include <map>
class foo {
public:
foo() {}
const double & operator[](const std::string key) const {
return data[key];
}
private:
static const std::set<std::string> validkeys;
std::map<std::string, double> data;
};
const std::set<std::string> foo::validkeys = {"foo1", "foo2"};
当我编译这个(使用G ++与-std = C++ 0x中),我得到这个编译错误:
|| /home/luke/tmp/testmap.cc: In member function 'double& foo::operator[](std::string) const':
testmap.cc|10 col 22 error| passing 'const std::map<std::basic_string<char>, double>' as
'this' argument of 'mapped_type& std::map<_Key, _Tp, _Compare, _Alloc>::operator[](const
key_type&) [with _Key = std::basic_string<char>, _Tp = double, _Compare =
std::less<std::basic_string<char> >, _Alloc = std::allocator<std::pair<const
std::basic_string<char>, double> >, mapped_type = double, key_type =
std::basic_string<char>]' discards qualifiers
没有我似乎解决这个问题。我曾尝试
- 使validkeys一个std ::设置和数据的std ::地图
- 使用为const char *而不是字符串
- 返回常量双或双,而不是常量双&
- 使用列表和向量而不是设置存储有效的键
我不知道我是否正确地接近这个问题,所以如果有其他简单的方法来创建一个类,允许这种类型的f性感:
foo a;
a["foo2"] = a["foo1"] = 5.0;
// This would raise a std::runtime_error because I would be checking that
// "foo3" isn't in validkeys
a["foo3"] = 4.0;
任何建议非常感谢。
SOLUTION
下面的工作正是我想要它,我甚至有一个基本的异常,当您尝试设置或一键搞定,是不是在一组有效键:
#include <iostream>
#include <string>
#include <map>
#include <set>
#include <stdexcept>
class myfooexception : public std::runtime_error
{
public:
myfooexception(const std::string & s)
: std::runtime_error(s + " is not a valid key.") {}
};
class foo {
public:
foo() {
for (std::set<std::string>::iterator it = validkeys.begin();
it != validkeys.end();
++it) {
data[*it] = 0.0;
}
}
const double & operator[](const std::string & key) const {
if (data.find(key) == data.end()) {
throw myfooexception(key);
} else {
return data.find(key)->second;
}
}
double & operator[](const std::string & key) {
if (data.find(key) == data.end()) {
throw myfooexception(key);
} else {
return data[key];
}
}
private:
static const std::set<std::string> validkeys;
std::map<std::string, double> data;
};
const std::set<std::string> foo::validkeys = {"foo1", "foo2"};
int main(void)
{
foo a;
a["foo1"] = 2.0;
a["foo1"] = a["foo2"] = 1.5;
// a["foo3"] = 2.3; // raises exception: foo3 is is not a valid key
const foo b;
std::cout << b["foo1"]; // should be ok
// b["foo1"] = 5.0; // compliation error, as expected: b is const.
return 0;
}
你为什么要做2次扫描的地图?您可以使用'find'并检查其结果 – davka 2012-02-20 08:06:46
谢谢。我将其更改为if(data.find(key)== data。结束()) – hazelnusse 2012-02-20 08:42:38
你还在做两次:) – davka 2012-02-20 11:16:51