无法捕获模板规范化方法抛出的异常

时间:2017-12-25 13:52:12

标签: c++ templates template-specialization

我们说我有以下代码:

//handler.hpp
template<typename T>
class handler
{
private:
    static void process_core(const T& request) { }
public:
    static void process(const T& request)
    {
        try
        {
            process_core(request);
        }
        catch(const std::exception& e)
        {
            std::cout << "exception " << e.what() << std::endl;
        }
    }
};

//string_handler.cpp
template<> void handler<std::string>::process_core(const std::string& s)
{
    std::cout << "string_handler" << std::endl;
    throw std::invalid_argument("bang");
}

//test.cpp
int main()
{
    handler<std::string>::process("123");
}

我认为std::invalid_arguemnt例外应该被抓住并处理,但事实并非如此。程序崩溃了:

string_handler
terminate called after throwing an instance of 'std::invalid_argument'
  what():  bang
Aborted (core dumped)

有趣的是:

  1. 将方法handler::process_core更改为

    static void process_core(const T& request);  // { } braces are removed
    
  2. 的工作原理。但是我不能这样做,因为process_core对于某些类型是可选的。 Q1:删除大括号后它为什么会起作用?

    1. 将源合并到一个文件(比如test.cpp)可以正常工作。 Q2:为什么?

    2. 问题3:正确的实施方式是什么?

1 个答案:

答案 0 :(得分:4)

您应该在main中使用它之前声明您的专业化,否则您的程序生成错误。 (你有正常的实例化和专业化冲突)。

  • 使用“1。”删除定义时,您没有定义冲突。
  • 在一个文件中合并时,在常规实例化之前声明(并定义)特化,所以它也可以。
  • 允许拆分不同文件的方法是声明特化,所以:

    //handler.hpp
    
    template<typename T>
    class handler
    {
     // ...
    };
    
    // Declare specialization
    template<> void handler<std::string>::process_core(const std::string& s);