函数名称的模板替换
Template substitution for function names
我正在使用第三方C++库,该库有一个 json 解析类,该类具有不同的功能,如下所示:
GetInt
GetBool
GetString
GetDouble
我想编写一个可以访问此类的实用程序函数。我在想这样的事情:
class <template T>
class MyClass {
static T getValue(ThirdPartyClass someObj, const string &key) {
if(someObj[key].IsDouble())
return someObj[key].GetDouble();
else if (someObj[key].IsString())
return someObj[key].GetString();
// ... (for other types)
}
}
此类的调用方将保存正确的返回类型。
然而,这是丑陋的。有什么方法(例如使用宏替换)可以避免 if 条件吗?第三方类具有 IsXXTypeXX 和相应的 GetXXTypeXX 函数(其中 XXTypeXX 是 Int、Double、String 或 Bool)。
当我调用函数时,我知道返回类型,例如:
int i = getValue(someObj, "intKey");
string s = getValue(someObj, "strKey");
所以我根本不需要 if 条件。理想情况下,我会期待拥有这样的东西我将能够做到这一点:
int i = MyClass<int>::getValue(someObj, "intKey");
string s = MyClass<string>::getValue(someObj, "strKey");
为什么不编写一堆静态 Get 函数(GetInt/GetDouble...)来验证输入,返回适当的类型结果,如果不是该类型,则引发异常?
从技术上讲,您可以实现您在那里概述的公共接口,但这将涉及非常丑陋的模板专业化。如果你只有一堆静态函数,可能会更好。以下是模板专用化的外观:
template <typename T> class MyClass {
static T getValue(ThirdPartyClass someObj, const string &key) {
// handle types that you didn't specialize for
}
};
template <> class MyClass <string> {
static string getValue(ThirdPartyClass someObj, const string &key) {
return someObj[key].GetString();
}
};
template <> class MyClass <int> {
static int getValue(ThirdPartyClass someObj, const string &key) {
return someObj[key].GetInt();
}
};
//..
软件工程的骨架关键:添加一个中间层。
#include <string>
#include <cassert>
using std::string;
class Proxy {
public:
enum Type {
Int,
Bool,
String,
Double
};
Type type;
int i;
bool b;
string s;
double d;
operator int() const {
assert(type == Int);
return i;
}
operator bool() const {
assert(type == Bool);
return b;
}
operator string() const {
assert(type == String);
return s;
}
operator double() const {
assert(type == Double);
return d;
}
Proxy(int i) : type(Int), i(i) {}
Proxy(bool b) : type(Bool), b(b) {}
Proxy(string s) : type(String), s(s) {}
Proxy(double d) : type(Double), d(d) {}
}; // class Proxy
Proxy getValue(ThirdPartyClass someObj, const string &key) {
if (someObj[key].IsDouble())
return someObj[key].GetDouble();
else if (someObj[key].IsString())
return someObj[key].GetString();
//... (for other types)
}
int main() {
int i = getValue(someObj, "intKey"); // if type does not match, a exception will be thrown.
string s = getValue(someObj, "strKey");
}
您显示的代码无法编译。你不能在同一个函数中返回一个double
、一个string
和一个int
。你必须做什么,它专门针对每个返回类型,然后只调用该类型的函数:
template <>
class MyClass<int> getValue(ThirdPartyClass someObj, const string& key) {
if(someOjb[key].IsInt()) return someObj[key].GetInt();
else { /* Maybe throw an exception */ }
};
并对每种类型重复此操作。
现在,你可能会想,"这很愚蠢,为什么我必须专门研究每种类型?这是因为您的 JSON 库正在使用类型擦除,因此您必须在运行时检查类型。保存工作的唯一方法是库提供模板化get
。
如果需要,可以创建一个宏来标记这些实例化。它将利用预处理器的#
(字符串化)和##
(串联)功能。把它们写出来可能会更清楚。
相关文章:
- 为什么除非添加括号,否则构造函数上的模板替换会失败?
- 用符号版本替换对函数的所有调用
- 我可以在这里替换什么,因为我不能在 C# 中使用隐式变量的 lambda 函数?
- 用矩阵将函数中的整数值替换定义的常量
- 函数模板实例化、替换和重载解析的顺序是什么?
- 为表示一个或多个操作的C++函数的int参数寻找类型安全的替换
- 仅当一个参数中未使用 std::function 时,模板函数替换才有效
- 为什么数组中对象的析构函数在被另一个对象替换时不被调用?
- 如何使替换 c 函数的变量名成为错误?
- hstrerror() 的替换函数
- 重新声明时替换函数默认参数
- C++字符串替换函数无限循环
- 如何在c++中替换函数调用的所有实例
- 用C++模板替换函数调用的C宏
- 使用字符串替换函数将字符串的一部分替换为初始化的变量
- 字符串替换函数c++
- 使用默认类型替换c++函数引用模板错误
- 在Std::to_string替换函数中无法识别Std::stringstream对象
- c++中的替换函数
- 替换函数'operator new'不能声明'inline' [-werror,-winline-new-delete]