【问题标题】:C++ Exception syntaxC++ 异常语法
【发布时间】:2014-02-25 19:25:32
【问题描述】:

我无法理解异常的语法。我有一个必须能够抛出异常的类模板map<T>。下面的代码是正确的,是用来捕获异常的。

try
{       
    map<int> m;
    m["everything"] = 42;
}
catch(map<int>::Uninitialized&)
{
    cout << "Uninitialized map element!" << endl;
}

我试图创建一个派生自 runtime_error 的类,然后将其从我的类中抛出。但看来我的逻辑有问题。

class Uninitialized : public runtime_error
{
public:
    Uninitialized() : runtime_error("error") {}
};

T operator[] (const char index[]) const
{
    throw Uninitialized();
    return value;
}

【问题讨论】:

  • 您遇到了哪些编译器错误?你的预期结果是什么,你实际得到了什么?请澄清您的问题。
  • 错误多得我数不过来xD 我基本上用什么来捕获异常的代码。我相信这个问题与我投掷的方式和我抓的方式有关。
  • 旁白:鉴于已经有一个std::map,您最好使用不同的名称。
  • 你的逻辑在什么方面看起来有缺陷?你的前提是什么,你得出了什么结论?
  • 异常被捕获的方式确实与被抛出的方式相对应。它被捕获为未命名的非常量引用?

标签: c++ templates exception exception-handling


【解决方案1】:

您尝试做的基本想法当然是可能的,因此您遇到的确切问题并不完全清楚。

这是一个可以正常工作的快速演示,大致完成了您似乎正在尝试的操作:

#include <stdexcept>
#include <iostream>

template <class T>
class map { 
public:
    class Uninitialized : public std::runtime_error
    {
    public:
        Uninitialized() : runtime_error("error") {}
    };

    T operator[](const char index[]) const
    {
        throw Uninitialized();
        return T();
    }
};

int main(){ 
    map<int> m;
    try {
        auto foo = m["a"];
    }
    catch (map<int>::Uninitialized &m) {
        std::cerr << "Caught exception:" << m.what()<< "\n";
    }
}

【讨论】:

  • 我相信问题与此有关。现在正在尝试修复它。
  • Downvoter:愿意解释一下您在这里看到的问题吗?如果真的有问题,我想解决它...
  • 15.3/17 似乎与您的断言相矛盾,即非常量引用不能绑定到临时对象。不管throw表达式中的异常是否是临时的,它都是用来初始化异常对象的,它肯定是临时的(15.1/3)。此外,用户对该问题的第一条评论表明该问题是通过将runtime_error 基类添加到异常而引入的编译器错误。我认为投掷或接球的方法没有改变。代码一直不正确吗?如果不是,改变的血统对它有何影响?
  • 我相信 Rob 是正确的。 (参见例如here。)我认为您可以通过非常量引用捕获异常,否则 Boost.Exception 没有多大意义。
  • @RobKennedy:是的——至少在这一点上已更正(不能删除,因为它已被接受)。
【解决方案2】:

假设您正在创建一个map 类型(尽管标准库已经提供了一个)。您提供operator[],并希望它在每次有人尝试访问不存在的密钥时抛出异常。

创建你的异常类:

class unititialized_access : public std::runtime_error
{
    // typical stuff
};

那么,在map&lt;Key, Value&gt;::operator[]内:

if (<key doesn't exist>)
    throw unititialized_error("blah blah");

您可以通过以下方式捕获异常:

try
{
    m["foo"] = 42;
}
catch (const unitialized_error& e)
{
    // do something
}

【讨论】:

  • 我不应该更改这一行:catch(map::Uninitialized&) 我的类必须被构建,这样才能使用它。
  • 好的,让uninitialized_error成为map的成员。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2013-07-29
  • 2023-03-20
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多