2012-03-05 53 views
5

我有一个包含地图重载操作符不抛出异常

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 "); 
    } 
} 

我希望它当现场没有在地图中存在这样的程序不上一个糟崩溃抛出异常的一类,但是抛出对重载运算符似乎不起作用,程序崩溃无论如何抛出或抛出都被忽略。如果我使用相同的代码,但具有共同的功能

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; 
} 

,并发生崩溃,因为提升的断言上任何试图转换未初始化的变量。这种方法可能是用在地图上插入,像

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

所以我想我也没有办法,当操作人员上的归因理论或一个GET和使用该运营商用于区分是非常不安全得到

+0

我个人把'find'并在不同线路上 – pkit 2012-03-05 13:03:53

+1

这是比较(可能)不是你的问题的原因,但你需要按值返回 - 你不能返回一个临时引用。 – 2012-03-05 13:07:08

+0

@pkit并在定义它的语句中初始化“it”。 – 2012-03-05 13:17:53

回答

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); 
    } 
}; 
+0

代理+1。 “代理”模式“经常被忽视,尽管它可能是我见过的最不稳定的模式之一。 – 2012-03-05 14:39:44