具有std::map成员变量的类的下标运算符
subscript operators for class with std::map member variable
我正在尝试创建一个类,该类封装std::map,并进行检查以确保键是批准的有效字符串之一,还将映射初始化为所有批准的有效串的默认值。我在让下标运算符工作时遇到了问题,特别是它的const版本
这是我的类原型代码:
#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"};
当我编译这个(使用带有-std=c++0x的g++)时,我得到了以下编译错误:
|| /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::set和数据std::map
- 使用const char*而不是字符串
- 返回const double或double而不是const double&
- 使用list和vector而不是set来存储validkeys
我不知道我是否正确地处理了这个问题,所以如果有其他简单的方法来创建一个允许这种功能的类:
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;
非常感谢任何建议。
解决方案
以下操作正是我想要的,当你试图设置或获取一个不在有效密钥集中的密钥时,我甚至有一个基本的例外:
#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;
}
operator []
在std::map
中没有声明为const
,因为operator []
在找不到键时还会插入一个新元素,并返回对其映射值的引用。如果希望operator[]
为const
,则可以使用map::find
方法而不是map::operator[]
。
std::map
的下标运算符是非常数的,因为它插入了一个新元素(如果还不存在的话)。如果您希望映射具有常量operator[]
,则需要编写一个使用map::find()
并针对map::end()
进行测试的映射,以处理错误情况。
您正试图修改常量对象!!请删除set.const的const。一旦初始化了成员,就不能修改它们。
您试图分配给std::map
,但您的函数被声明为const
,同时返回const
。删除两个const
,它应该可以工作。
相关文章:
- 一组值的零开销下标运算符
- 如何重载下标运算符 [] 以引用 2d STL 数组?
- 有什么理由不扩展 std::set 以添加下标运算符吗?
- 在继承的模板类中使用下标 [] 运算符
- 为什么函数的任何索引处的下标运算符在C++中总是返回1
- c++下标运算符到下级类向量
- 数组下标运算符 ([ ]) 对数组有什么作用?
- 双标具有下标运算符的原因是什么?
- 基成员的重载下标运算符
- SFINAE 为什么我没有检测到 std::vector 的下标运算符?
- 如何重载下标运算符以返回可以是左值的可选值?
- C++下标运算符的继承规则
- 使用带有下标运算符的赋值运算符将值分配给 std::map
- 如何从重载的下标 [] 运算符返回 std::unique_ptr&?
- 为下标运算符和函数调用运算符提供默认参数
- C++ 下标运算符
- 将类实例作为指针传递,并在此指针上使用过载的下标运算符
- 如何为模板类的下标运算符
- 如何在提升 lambda 中使用下标运算符
- "飞机"不提供下标运算符是什么意思"