2010-03-14 52 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