我正在使用第三方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");
答案 0 :(得分:1)
为什么不编写一堆静态Get函数(GetInt / GetDouble ...)来验证输入,返回相应的类型结果并抛出异常(如果不是那种类型)?
答案 1 :(得分:1)
从技术上讲,您可以实现您在那里概述的公共界面,但这将涉及非常难看的模板专业化。 如果你只是拥有一堆静态函数,那可能会更好。这是模板专业化的样子:
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();
}
};
//..
答案 2 :(得分:1)
软件工程的骨架键:添加中间层。
#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");
}
答案 3 :(得分:0)
您展示的代码无法编译。您不能在同一函数中返回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
。
如果需要,可以创建一个宏来标记这些实例化。它将利用预处理器的#
(stringification)和##
(concatenation)功能。将它们写出来可能会更清楚。