2013-10-21 70 views
1

讓我們考慮以下三個文件。從專門的方法捕捉異常

tclass.h:

#include <iostream> 
#include <vector> 

template<typename rt> 
class tclass 
{ 
public: 
    void wrapper() 
    { 
     //Storage is empty 
     for(auto it:storage) 
     { 
     } 

     try 
     { 
      thrower(); 
     } 
     catch(...) 
     { 
      std::cout << "Catch in wrapper\n"; 
     } 
    } 

private: 
    void thrower(){} 
    std::vector<int> storage; 
}; 

spec.cpp:

#include "tclass.h" 

//The exact type does not matter here, we just need to call the specialized method. 
template<> 
void tclass<long double>::thrower() 
{ 
    //Again, the exception may have any type. 
    throw (double)2; 
} 

main.cpp中:

#include "tclass.h" 
#include <iostream> 

int main() 
{ 
    tclass<long double> foo; 
    try 
    { 
     foo.wrapper(); 
    } 
    catch(...) 
    { 
     std::cerr << "Catch in main\n"; 
     return 4; 
    } 
    return 0; 
} 

我使用Linux的x64,GCC 4.7 。2,該文件被編譯使用此命令:

g++ --std=c++11 *.cpp

第一次測試:如果我們運行上面的程序,它說:

terminate called after throwing an instance of 'double' 
Aborted 

二測:如果我們在tclass.h文件發表評論for(auto it:storage),該程序將捕獲main函數中的例外。 WAT爲什麼?它試圖迭代空向量導致堆棧損壞嗎?

第三個測試:讓我們取消註釋for(auto it:storage)行並將方法專業化從spec.cpp移動到main.cpp。然後,例外被捕獲在wrapper。這怎麼可能,爲什麼可能的內存腐敗不會影響這種情況?

我也試着用不同的優化級別和-g進行編譯,但結果是一樣的。

然後我在Windows 7 x64,VS2012 Express上試了一下,用x64版本的cl.exe編譯,沒有額外的命令行參數。在第一次測試中,這個程序沒有產生任何輸出,所以我認爲它只是默默地崩潰,所以結果與Linux版本類似。對於第二次測試,它再次沒有輸出,所以結果與Linux不同。對於第三次測試,結果與Linux結果類似。

此代碼中是否有任何錯誤,因此它們可能會導致此類行爲?可能第一次測試的結果是由編譯器中可能存在的錯誤引起的?

+0

如何和:

spec.cpp:6: multiple definition of 'tclass<long double>::thrower()'

您可以在您的.h聲明專業化糾正代碼你在哪裏聲明和定義模板專業化? –

+0

@Juraj我專門研究'spec.cpp'中的'thrower'方法。我是否需要專門做其他事情才能使其正常工作? – Sergey

+0

@Juraj明白!當然,沒有必要專門研究整個類,但解決方案是在頭上添加聲明(即'template <> void tclass :: thrower();')。它適用於03和11.謝謝! – Sergey

回答

2

與您的代碼,我用gcc 4.7.1:

template<> void tclass<long double>::thrower();