为多个私有成员拥有多个get
方法会使类非常混乱。我想实现一个get
方法,该方法可以返回我需要的任何成员。
enum TYPE {INT, DOUBLE, DOUBLE2, STRING};
class Foo {
int i = 1;
double d = 2.5;
double d2 = 6.0;
string s = "string";
public:
template<typename T>
T get(TYPE type) {
switch (type) {
case INT:
return i;
case DOUBLE:
return d;
case DOUBLE2:
return d2;
case STRING:
return s;
}
}
该方法将如下使用:
Foo foo;
int integer = foo.get<int>(INT);
double d2 = foo.get<double>(DOUBLE2);
为什么不编译?
答案 0 :(得分:3)
您认为在这种情况下会发生什么?
TYPE t = DOUBLE;
if (rand() % 2 == 0) {
t = INT;
}
int i = foo.get<int>(t); // t might be INT or DOUBLE
这毫无意义,因为TYPE
参数是一个运行时值,并且您依靠它来选择返回类型,该类型必须在编译时就知道。
此外,当您执行switch
语句时,编译器具有可以编译整个switch语句,甚至包括可能未被调用的情况。
想象一下get<int>
成员函数被实例化:
template<>
auto get<int>(TYPE type) -> int {
switch (type) { // type might be anything
case INT:
return i; // return int
case DOUBLE:
return d; // return double
case DOUBLE2:
return d2; // return double
case STRING:
return s; // return string
}
}
无法编译。该函数显然会返回int
,但在某些分支中它将返回其他类型。
一种适当的解决方案是完全删除枚举并使用类似constexpr if
的符号来表示编译时分支,而不是发送类型名和值,而仅依赖于该类型名。
如果您想了解有关如何实现这种数据结构的更多信息,建议您阅读std::tuple