重载运算符不会抛出异常

时间:2012-03-05 12:49:58

标签: c++ exception operator-overloading

我有一个包含地图的课程

Any& Map::operator[]( const unsigned int field ) const
{
  try
  {
    iterator it;
    if ((it = m_fields.find(field)) != m_fields.end())
      return it->second;

    throw std::runtime_error("Field " + boost::lexical_cast<std::string>(field) + " not found.");
  }
  catch(boost::bad_any_cast& )
  {
    throw std::runtime_error("Failed conversion field " + boost::lexical_cast<std::string>(field)  + " using boost::any_cast ");
  }
}

我希望它在地图中不存在该字段时抛出异常,因此程序不会在错误的get上崩溃,但抛出似乎对重载的运算符不起作用,程序崩溃无论如何要么抛出或捕获被忽略。如果我使用相同的代码但具有通用功能

Any& Map::get( const unsigned int field ) const
{
  //...

它有效。

我是否遇到了某些c ++限制或者我做错了什么?

- 编辑:

我运行了调试器,令我惊讶的是代码甚至没有执行,另一种方法

Any& Map::operator[]( const unsigned int  field )
{
  iterator it;
  if ((it = m_fields.find(field)) == m_fields.end())
  {
    Any newValue;
    m_fields[field] = newValue;
    return m_fields[field];
  }

  return it->second;
}

并且由于尝试转换未初始化变量的Any上的提升断言而发生崩溃。此方法可能用于地图上的插入,如

Map a;
a[3] = "foo";

所以我想我无法区分何时将运算符用于归因或获取,并且使用此运算符对于获取非常不安全

1 个答案:

答案 0 :(得分:2)

重新编辑:重载决议一般只考虑到 参数,而不是用途。如果你有一个const和一个非const函数 如果使用其他相同的签名,则选择非const 可能的(例如调用非const对象)。

如果您确实需要根据使用情况采取不同的行为,请执行此操作 传统的解决方案是提供代理。你的Map课程会 包含两个函数getset,非const operator[]将返回一个 代理看起来像:

class Proxy  // member of Map
{
    Map* myOwner;
    int myIndex;
public:
    Proxy( Map* owner, int index )
        : myOwner( owner )
        , myIndex( index )
    {
    }
    void operator=( Any const& rhs ) const
    {
        myOwner->put( myIndex, rhs );
    }
    operator Any() const
    {
        return myOwner->get( myIndex );
    }
};