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

时间:2014-11-21 08:16:37

标签: c++ templates enums

我有一个包含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种以上的数据类型,如果我将它们全部列在switch case中,那么维护起来就太复杂了。

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

此致 燕化

2 个答案:

答案 0 :(得分:0)

您的此代码将强制编译器实现您的类的100个或更多变体,因为性能或可读性没有任何好处。如果你问我,这很简单。

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

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

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

忘记C ++将你的设计问题驱逐出去,这是我的建议。这种语言即使经过精心设计也能产生monstruosities,如果你故意要求它,那就更是如此。

答案 1 :(得分:0)

修改

我不知道你的评论是否适合运行时,所以下面的解决方案对你不起作用。 (但我在这里说的是它激发了你对不同实现的启发。

你必须知道一些事情:模板被评估为COMPILE时间,因此你不是一个有效的工具,因为你试图在RUNTIME评估类型。

您需要定义每种可能性。

弃用答案

解决方案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;
}