讓我們考慮以下三個文件。從專門的方法捕捉異常
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結果類似。
此代碼中是否有任何錯誤,因此它們可能會導致此類行爲?可能第一次測試的結果是由編譯器中可能存在的錯誤引起的?
如何和:
spec.cpp:6: multiple definition of 'tclass<long double>::thrower()'
您可以在您的.h聲明專業化糾正代碼你在哪裏聲明和定義模板專業化? –
@Juraj我專門研究'spec.cpp'中的'thrower'方法。我是否需要專門做其他事情才能使其正常工作? – Sergey
@Juraj明白!當然,沒有必要專門研究整個類,但解決方案是在頭上添加聲明(即'template <> void tclass :: thrower();')。它適用於03和11.謝謝! –
Sergey