C++ Can';t捕获模板特殊化方法引发的异常

C++ Can';t捕获模板特殊化方法引发的异常,c++,templates,template-specialization,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);

假设我有以下代码:

//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");
}
有趣的是:

  • 将方法
    handler::process\u core
    更改为

    static void process_core(const T& request);  // { } braces are removed
    
  • 工作。但是我不能这样做,因为对于某些类型,
    process\u core
    是可选的。问题1:为什么在移除支架后它会起作用

  • 将源代码合并到单个文件(比如
    test.cpp
    )是可行的。问题2:为什么

  • 问题3:正确的实施方式是什么


  • 您应该在main中使用专门化之前声明它,否则您的程序是格式错误的。(您有冲突的常规实例化和专门化)

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

      //handler.hpp
      
      template<typename T>
      class handler
      {
       // ...
      };
      
      // Declare specialization
      template<> void handler<std::string>::process_core(const std::string& s);
      
      //handler.hpp
      模板
      类处理程序
      {
      // ...
      };
      //宣布专业化
      模板void handler::process_core(const std::string&s);
      

    • handler
      T
      是从生成的源代码编译而来的,我不想添加很多头文件,例如XXX_handler.hpp。有什么想法吗?有两个典型的逐点专门化声明,靠近要专门化的方法(如我所建议的),靠近我们专门化的类(因此内置类型不可能,std/3rd库类型更难).我认为所有模板专门化和模板类成员函数实现的主体必须在类之外声明。您还应该尝试在类外部声明进程_core()的默认(空)主体。
      //handler.hpp
      
      template<typename T>
      class handler
      {
       // ...
      };
      
      // Declare specialization
      template<> void handler<std::string>::process_core(const std::string& s);