获取可以使用模板返回不止一种类型的方法

时间:2019-04-17 18:32:33

标签: c++ templates

为多个私有成员拥有多个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);

为什么不编译?

1 个答案:

答案 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