2010-03-14 91 views
4

我有一个问题,为嵌套在模板中的类的异常编写catch子句。更具体地讲,我有模板和异常的定义如下:捕捉嵌套模板异常[C++]

/** Generic stack implementation. 
    Accepts std::list, std::deque and std::vector 
    as inner container. */ 
template < 
typename T, 
    template < 
     typename Element, 
     typename = std::allocator<Element> 
    > class Container = std::deque 
> 
class stack { 
public: 
    class StackEmptyException { }; 
    ... 

    /** Returns value from the top of the stack. 
     Throws StackEmptyException when the stack is empty. */ 
    T top() const; 
    ... 
} 

我有我想要的异常赶上下面的模板方法:

template <typename Stack> 
void testTopThrowsStackEmptyExceptionOnEmptyStack() { 
    Stack stack; 
    std::cout << "Testing top throws StackEmptyException on empty stack..."; 

    try { 
     stack.top(); 
    } catch (Stack::StackEmptyException) { 
     // as expected. 
    } 

    std::cout << "success." << std::endl; 
} 

当我编译它(-Wall , - penantic)我得到以下错误:

In function ‘void testTopThrowsStackEmptyExceptionOnEmptyStack()’: 
error: expected type-specifier 
error: expected unqualified-id before ‘)’ token 
=== Build finished: 2 errors, 0 warnings === 

在此先感谢您的帮助!

有趣的是,如果堆栈实现不是模板,那么编译器会接受原样的代码。

PS。我也尝试重新定义模板方法类型,但我无法完成这项工作。

+1

@卡洛尔,因为你是新来的土地:如果你发现你的问题解决了,你应该选择一个答案为“接受”(点击左边的标记来回答)。所以人们可以看到你的问题已经通过答案解决了。 – 2010-03-14 17:10:48

+0

顺便说一句,你是否真的需要每种不同类型的堆栈来抛出不同类别的异常? 'stack :: StackEmptyException'和'stack :: StackEmptyException'是不相关的类型。如果你想在代码中更高的位置捕获它,那么知道有一个正在使用的堆栈,但不知道(或需要知道)哪个堆栈? – 2010-03-14 17:11:57

+0

我同意Steve的观点,我通常不会在模板类中创建新的异常作为嵌套类。我更喜欢创建一个基类(比如'BaseStack')来定义我的异常,并让每个模板类'Stack '从'BaseStack'继承,这样我就有可能在模板代码之外捕获这些异常而不用枚举所有可能的模板专业化。 – 2010-03-14 17:26:42

回答

9

使用typename

template <typename Stack> 
void testTopThrowsStackEmptyExceptionOnEmptyStack() { 
    Stack stack; 
    std::cout << "Testing top throws StackEmptyException on empty stack..."; 

    try { 
     stack.top(); 
    } catch (typename Stack::StackEmptyException) { 
     // as expected. 
    } 

    std::cout << "success." << std::endl; 
} 

编译器的解析器,否则假定Stack::StackEmptyException不是一个类型和misparses代码(它不能知道这是一个类型,因为在这一点上它不” t知道Stack是什么类型,所以潜在的StackEmptyException也可以是静态数据成员)。你通常也应该通过引用而不是按价值来捕获。

+0

它的工作原理,非常感谢! – Karol 2010-03-14 16:44:49

+0

请参阅常见问题解答:http://womble.decadentplace.org.uk/c++/template-faq.html – 2010-03-14 16:45:48

+0

我会。谢谢! – Karol 2010-03-14 18:33:03