如何根据 2 个枚举值检查创建具有 2 个数据类型参数C++模板类

How to create C++ template class with 2 datatype parameters based on 2 enum values checking?

本文关键字:类型参数 数据 C++ 创建 何根 枚举 检查      更新时间:2023-10-16

我有一个包含 2 个类型参数的模板类。当我创建类实例时,我需要检查其他 2 个枚举值来确定这个类类型参数。

enum DataType_t
{
    DATA_TYPE_INT32 = 1,
    DATA_TYPE_FLOAT = 2,
    DATA_TYPE_DOUBLE = 3
    // totally more then 10 type enum value,
};
class MyClassBase
{};

template<typename InputDataType, typename OutputDataType>
class MyClass:public MyClassBase
{
private:
    InputDataType inputData;
    OutputDataType outputData;
public:
    MyClass() {};
    ~MyClass() {};
};
MyClassBase* make_instance(DataType_t inputDataType, DataType_t outputDataType)
{
    switch (inputDataType)
    {
    case DATA_TYPE_INT32:
        switch (outputDataType)
        {
        case DATA_TYPE_INT32:
            return new MyClass<int, int>();
        case DATA_TYPE_FLOAT:
            return new MyClass<int, float>();
        case DATA_TYPE_DOUBLE:
            return new MyClass<int, double>();
        }
        break;
    case DATA_TYPE_FLOAT:
        switch (outputDataType)
        {
        case DATA_TYPE_INT32:
            return new MyClass<float, int>();
        case DATA_TYPE_FLOAT:
            return new MyClass<float, float>();
        case DATA_TYPE_DOUBLE:
            return new MyClass<float, double>();
        }
        break;
    case DATA_TYPE_DOUBLE:
        switch (outputDataType)
        {
        case DATA_TYPE_INT32:
            return new MyClass<double, int>();
        case DATA_TYPE_FLOAT:
            return new MyClass<double, float>();
        case DATA_TYPE_DOUBLE:
            return new MyClass<double, double>();
        }
        break;
    default:
        break;
    }
    return NULL;
}

我可以像上面这样写make_instance函数,但我觉得这不是一种优雅的方式。 实际上,枚举DataType_t定义了 10 多种数据类型,如果我将它们全部列在开关大小写中,维护起来就太复杂了。

我想知道是否有更好的方法来处理这种情况?我的项目使用的是 C++98,还没有升级到 C++11。谢谢。

问候燕华

你的这段代码将强制编译器实现你的类的 100 个或更多变体,而不会提高性能或可读性。如果你问我,这简直太疯狂了。

有人可能想知道为什么你首先需要动态实例化,但你肯定有一个很好的理由......

您可以对数据使用双精度,如果您需要完美的整数精度,则可以对整数值进行专用化。

然后,您可以存储数据类型,假设您需要一些特定的处理,例如根据原始类型显示数字,这甚至可能不是必需的。

忘记C++魔术消除你的设计问题,这是我的建议。这种语言即使经过精心设计也能产生怪物,如果你故意要求它,那就更是如此。

编辑

自从您的评论以来,我不知道这是用于运行时的,因此下面的解决方案对您不起作用。(但我在这里让它激发你进行不同的实现。

你必须知道一些事情:模板是在编译时计算的,因此不是一个有效的工具,因为你试图在运行时计算类型。

您将需要定义每种可能性。

已弃用的答案

解决方案 1

在这种情况下,您为什么不只使用using关键字?

using DATA_TYPE_FLOAT = float;
using DATA_TYPE_INT32 = int;
const auto my_c = MyClass<DATA_TYPE_INT32, DATA_TYPE_FLOAT>(); 

解决方案 2

更改make_函数的用途。就像 STL 一样,您应该构建传递参数的对象,这些参数将由您的MyClass持有。在你的情况下,你做错了。这是我的解决方案:

#include <type_traits>
template <typename I, typename O>
class MyClass {
    private:
        I input;
        O output;
    public:
        MyClass(const I& new_input, const O& new_output)
        : input(new_input), output(new_output) {}
};
template <typename I, typename O>
auto make_instance(I input, O output) -> MyClass<typename std::decay<I>::type, typename std::decay<O>::type> {
    return MyClass<typename std::decay<I>::type, typename std::decay<O>::type>(input, output);
}
int main() {
    const auto c = make_instance(4, 3.2);
    return 0;
}