2013-10-21 43 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();