如何使用模板设置union的字段

时间:2016-02-25 10:45:18

标签: c++ templates

我的代码看起来像这样:

typedef enum {STR, INT, FLOAT} Type;
struct MyStruct
{
   Type type;
   union
   {
       std::string str;
       int i;
       float f;
   } value;    
};

我正试图以这种方式设置值:

template<typename T> void setValue(T data)
{
    switch(this->getType())
    {
        case Type::STR:
            this->str = data;
            break;
        case Type::INT:
            this->i = data;
            break;
        case Type::FLOAT:
            this->f = data;
            break;
        default:
            // Throw an exception
            break;
    }
}

所以,在我看来,所有看起来都很棒,但是我得到一个错误(例如在设置int值时):myStructInstance.setValue&lt; int&gt;(10);

error: cannot convert ‘const std::basic_string<char>’ to ‘int’ 

为什么呢?我想设置int字段,而不是字符串。

2 个答案:

答案 0 :(得分:2)

正如Jarod和StoryTeller所说,所有分支都应该是有效的。您可以通过模板专业化传递:

template<typename T> void setValue(T data)
{
    switch(this->getType())
    {
    case Type::INT:
        this->i = data;
        break;
    case Type::FLOAT:
        this->f = data;
        break;
    default:
        // Throw an exception
        break;
    }
}

template<> void setValue(std::string data)
{
    switch(this->getType())
    {
    case Type::STR:
        this->str = data;
        break;
    default:
        // Throw an exception
        break;
    }
}

答案 1 :(得分:1)

在使用某种给定类型实例化模板后,setValue函数的整个主体需要进行类型检查。

您可以使用普通重载,而不是使用一个大函数:

void setValue(const std::string &data)
{
    if (this->getType() != Type::STR) {
      // Throw
    }
    this->value.str = data;
}

// dito for other Type values.