运行时类型定义

Runtime type definition

本文关键字:定义 类型 运行时      更新时间:2023-10-16

我的问题是关于动态更改/设置一个类型的定义,检查一个变量的值,这个变量可以在运行时更改,比如这个简单的例子:

void changeMode(int mode)
{
    if(mode == 1)
    {
            typedef MyType float;
    }
    else if(mode == 2)
    {
            typedef MyType double;
    }
}
int main(int argc, char *argv[])
{
    MyType (2);
    MyType A = 3;
    MyType B = 2;
    MyType C = A + B;
    return 0;
}

有可能吗?这是典型的模板案例吗?是否可以避免使用模板?我的目标是集中类型定义,以便在运行时进行切换,而无需将其扩展到每个类,也无需为将使用给定类型的每个类/函数使用"模板"。

typedef是在编译时评估的,因此没有

但是你可以使用前置处理器做这样的事情:

#ifdef TYPE_FLOAT
   typedef float Type;
#else
   typedef int Type;
#endif

但请记住,它是在编译时

您可以提取依赖于类型的代码到函数模板(或者在更复杂的情况下提取类模板):

template <typename MyType>
void ExecuteTypeDependentCode()
{
    MyType A = 3;
    MyType B = 2;
    MyType C = A + B;
}

然后你可以编写包装器,它的任务是在模式之间切换:

enum Modes
{
    FloatMode = 1,
    DoubleMode = 2
};
void ExecuteTypeDependentCode(Modes mode)
{
    switch (mode)
    {
        case FloatMode:
            ExecuteTypeDependentCode<float>();
            break;
        case DoubleMode:
            ExecuteTypeDependentCode<double>();
            break;
    }
}

使用示例:

int main(int argc, char *argv[])
{
    ExecuteTypeDependentCode(DoubleMode);
    return 0;
}

切换的过程只能写一次(我在这里描述了这种方法)。

Typedef是静态评估的,因此您需要做一些类似于拥有"模板的经典情况"(不管是什么:)的事情

template <int Mode>
struct Dispatch { };
template <>
struct Dispatch <0> {
    using U = int; // fancy way of saying typedef
};
template <>
struct Dispatch <1> {
    using U = char; // feel free to use typedef
};
int main() {
    Dispatch<0>::U x; // compile time constant in <> (zero)
    x = 5;
    Dispatch<1>::U y; // compile time constant in <> (one)
    y = 'c';
}

正如其他答案所指出的,这是不可能通过typedef实现的。然而,您可以使用多主体包装器类来模拟这种行为:

#include <cstdio>

class Gen
{
public:
    static int mode;
    static Gen* get()
    {
        switch(mode)
        {
        case 1:
            return new GenFloat();
        case 2:
            return new GenDouble();
        }
        return NULL;
    }
};
int Gen::mode = 0;
class DoubleGen : public Gen
{
public:
    DoubleGen() : d(0) {}
    DoubleGen(double val) : d(val) {}
    double d;
};
class FloatGen : public Gen
{
public:
    FloatGen() : f(0) {}
    FloatGen(float val) : f(val) {}
    float f;
};


int main(void)
{
    Gen::mode = 1;
    Gen* _float = gen::get();
    gen::mode = 2;
    Gen* _double = gen::get();
    delete _float;
    delete _double;
    return 0;
}