无法捕获模板特殊化方法引发的异常

Che*_*hen 3 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");
}
Run Code Online (Sandbox Code Playgroud)

我认为std::invalid_arguemnt应该捕获并处理异常,但事实并非如此。程序崩溃:

string_handler
terminate called after throwing an instance of 'std::invalid_argument'
  what():  bang
Aborted (core dumped)
Run Code Online (Sandbox Code Playgroud)

有趣的事情是:

  1. 将方法更改handler::process_core

    static void process_core(const T& request);  // { } braces are removed
    
    Run Code Online (Sandbox Code Playgroud)

作品。但是我不能这样做,因为process_core对于某些类型是可选的。Q1:为什么删除括号后它可以工作?

  1. 将源合并到一个文件中(例如test.cpp)是可行的。Q2:为什么?

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

Jar*_*d42 6

您应该在main中使用它之前声明您的专业化,否则您的程序格式不正确。(您有冲突的常规实例化和专业化之一)。

  • 当删除带有“ 1”的定义时,您没有定义冲突。
  • 当合并到一个文件中时,您可以在常规实例化之前声明(并定义)专业​​化,因此也可以。
  • 允许分割为不同文件的方法是声明特殊化,因此:

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