c++ - c ++模板特化与派生类
问题描述
我在尝试专门化类的模板方法以接受派生类时遇到问题。我也尝试过使用指针,但最终遇到的问题比这次迭代要多得多。
#include <iostream>
using namespace std;
class Json {
public:
Json(){}
virtual ~Json(){}
template <class T>
bool Get(std::string key, T& value);
};
template <class T>
bool Json::Get(std::string key, T& value){
std::cout << "Call default GET" << std::endl;
}
template <>
bool Json::Get(std::string key, Json& value){
std::cout << "Call JSON GET" << std::endl;
}
class JsonError : public Json {
public:
JsonError(){}
~JsonError(){}
};
int main()
{
// OK
int int_value = 0;
Json json;
json.Get("int", int_value);
// OK
Json json_value;
json.Get("json", json_value);
// NOT OK
JsonError json_error_value;
json.Get("error", json_error_value);
return 0;
}
这应该打印出来
Call default GET
Call JSON GET
Call JSON GET
解决方案
这不是模板的工作方式。模板推导总是在确切的类型上,在这种情况下JsonError
,所以特化 forJson&
不匹配。
如果你仍然想让它工作,你可以用一个成员函数来重载模板函数Json&
。模板函数仍然会更好地匹配派生类型,因此我们还需要禁用任何派生自 的类型的模板方法Json
。
#include <iostream>
class Json {
public:
Json(){}
virtual ~Json(){}
template <class T, std::enable_if_t<!std::is_base_of_v<Json, T>, int> = 0>
bool Get(std::string key, T& value);
bool Get(std::string key, Json& value);
};
template <class T, std::enable_if_t<!std::is_base_of_v<Json, T>, int> = 0>
bool Json::Get(std::string key, T& value){
std::cout << "Call default GET" << std::endl;
return true;
}
bool Json::Get(std::string key, Json& value){
std::cout << "Call JSON GET" << std::endl;
return true;
}
class JsonError : public Json {
public:
JsonError(){}
~JsonError(){}
};
int main()
{
// OK
int int_value = 0;
Json json;
json.Get("int", int_value);
// OK
Json json_value;
json.Get("json", json_value);
// NOW IT'S OK
JsonError json_error_value;
json.Get("error", json_error_value);
return 0;
}
推荐阅读
- node.js - npm 安装错误;npm WARN tar EPERM: operation not allowed, futime
- google-apps-script - Google 表格 On Edit 触发器需要一些调整
- javascript - 使用 CryptoJS 解密 AES 密文
- python - 使用 python 线程为 Maya 创建 GIF
- firebase - Firebase 存储项目级别权限
- kubernetes - Istioctl 安装错误无法识别“STDIN”:版本“networking.istio.io/v1alpha3”中的种类不匹配
- r - r raster 如何将日期信息保存在 z 变量中
- javascript - 手动运行一个 husky git 钩子(不使用 git 命令触发它)
- javascript - 用于网页前端的 Java Scripting
- java - 将 Highcharts 图表添加到使用 Java API 生成的 JasperReport 模板