c++ - 具有 std::map 成员变量的类的下标运算符

标签 c++ constants stdmap subscript-operator

我正在尝试创建一个包装 std::map 的类,并进行检查以确保键是批准的有效字符串之一,并且还将映射初始化为具有所有批准的有效字符串的默认值。我在让下标运算符工作时遇到问题,特别是它的 const 版本。

这是我的类原型(prototype)代码:

#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::set 和数据 std::map
  • 使用 const char * 而不是字符串
  • 返回 const double 或 double 而不是 const double &
  • 使用 list 和 vector 而不是 set 来存储有效键

我不知道我是否正确地解决了这个问题,所以如果有其他一些简单的方法来创建一个允许这种功能的类:

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;

非常感谢任何建议。

解决方案

下面的工作完全符合我的要求,当您尝试设置或获取不在有效 key 集中的 key 时,我什至有一个基本的异常:

#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[],则可以使用 map::find 方法代替 map::operator[]常量.

关于c++ - 具有 std::map 成员变量的类的下标运算符,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9357308/

相关文章:

java - 私有(private)静态最终字符串或私有(private)最终字符串

c++ - 如何访问结构中定义的变量

c++ - 带有/不带有编译器的 C/C++ IDE

c++ - 为什么 FFMPEG 录屏视频速度快?

c++ - 无法在 z/OS 1.12 C++ 编译器错误中加载 CCNEP?

c++ - 从链接列表打印值,起始值作为函数中的默认值

c++ - 如何允许临时对象使用非常量复制构造函数

c++ - 常量和文字之间的混淆?

c++ - 如何使用 std::maps 和用户定义的类型作为键?

c++ - 有没有办法使用 std::copy 复制不冲突的映射值?