我们说我有以下代码:
//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)
有趣的是:
将方法handler::process_core
更改为
static void process_core(const T& request); // { } braces are removed
的工作原理。但是我不能这样做,因为process_core
对于某些类型是可选的。 Q1:删除大括号后它为什么会起作用?
将源合并到一个文件(比如test.cpp
)可以正常工作。 Q2:为什么?
问题3:正确的实施方式是什么?
答案 0 :(得分:4)
您应该在main中使用它之前声明您的专业化,否则您的程序生成错误。 (你有正常的实例化和专业化冲突)。
允许拆分不同文件的方法是声明特化,所以:
//handler.hpp
template<typename T>
class handler
{
// ...
};
// Declare specialization
template<> void handler<std::string>::process_core(const std::string& s);