Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/templates/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 如何设置并集';s字段使用模板_C++_Templates - Fatal编程技术网

C++ 如何设置并集';s字段使用模板

C++ 如何设置并集';s字段使用模板,c++,templates,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->

我的代码如下所示:

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;
    }
}
模板无效设置值(T数据)
{
开关(此->getType())
{
案例类型::STR:
这->str=数据;
打破
案例类型::INT:
这个->i=数据;
打破
案例类型::浮动:
这->f=数据;
打破
违约:
//抛出异常
打破
}
}
因此,在我看来,一切看起来都很好,但我得到了一个错误(例如,在设置int值时):myStructInstance.setValue(10)

错误:无法将'const std::basic_string'转换为'int'

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

正如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;
    }
}
模板无效设置值(T数据)
{
开关(此->getType())
{
案例类型::INT:
这个->i=数据;
打破
案例类型::浮动:
这->f=数据;
打破
违约:
//抛出异常
打破
}
}
模板无效设置值(std::字符串数据)
{
开关(此->getType())
{
案例类型::STR:
这->str=数据;
打破
违约:
//抛出异常
打破
}
}

正如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;
    }
}
模板无效设置值(T数据)
{
开关(此->getType())
{
案例类型::INT:
这个->i=数据;
打破
案例类型::浮动:
这->f=数据;
打破
违约:
//抛出异常
打破
}
}
模板无效设置值(std::字符串数据)
{
开关(此->getType())
{
案例类型::STR:
这->str=数据;
打破
违约:
//抛出异常
打破
}
}

一旦使用某个给定类型实例化模板,您的
setValue
函数的整个主体都需要进行类型检查

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

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

// dito for other Type values.

一旦使用某个给定类型实例化模板,整个
setValue
函数体都需要进行类型检查

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

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

// dito for other Type values.

所有分支都应该是有效的。为了详细说明Jarod42所说的,当函数模板被实例化为实际函数时,其中的所有代码都必须是有效的。您的联合看起来很奇怪:将指针存储在std::string而不是变量上。我不知道它有什么特点,但我不相信它会起作用。@Pierreemanuellallemant,这是c++11及更高版本。定义得很好。作为旁注,你不需要给工会命名。成员的名称将被注入到结构中。编辑:似乎您已经这样做了,因为代码是这样写的。所有分支都应该是有效的。为了详细说明Jarod42所说的,当函数模板被实例化为实际函数时,其中的所有代码都必须是有效的。您的联合看起来很奇怪:将指针存储在std::string上而不是变量上。我不知道它有什么特点,但我不相信它会起作用。@Pierreemanuellallemant,这是c++11及更高版本。定义得很好。作为旁注,你不需要给工会命名。成员的名称将被注入到结构中。编辑:似乎您已经这样做了,因为代码就是这样编写的。