C ++中的union和非默认的可构造对象

时间:2010-11-25 12:47:10

标签: c++ unions

我的程序中有一种情况,我需要从字符串转换为各种类型,显然结果只能是一种类型。所以我选择创建一个union并将其称为变体,如下:

union variant
{
    int v_int;
    float v_float;
    double v_double;
    long v_long;
    boost::gregorian::date v_date; // Compiler complains this object has a user-defined ctor and/or non-default ctor. 
}; 

我使用它如下:

bool Convert(const std::string& str, variant& var)
{
    StringConversion conv;

    if (conv.Convert(str, var.v_int))
        return true;
    else if (conv.Convert(str, var.v_long))
        return true;
    else if (conv.Convert(str, var.v_float))
        return true;
    else if (conv.Convert(str, var.v_double))
        return true;
    else if (conv.Convert(str, var.v_date))
        return true;
    else 
        return false;
}

然后我在这里使用该功能:

while (attrib_iterator != v_attributes.end())  //Iterate attributes of an XML Node
            {
                //Go through all attributes & insert into qsevalues map
                Values v;  // Struct with a string & boost::any
                v.key = attrib_iterator->key; 
                ///value needs to be converted to its proper type.
                v.value = attrib_iterator->value;
                variant var;
                bool isConverted = Convert(attrib_iterator->value, var); //convert to a type, not just a string
                nodesmap.insert(std::pair<std::string, Values>(nodename, v));
                attrib_iterator++;
            }

问题在于,如果我使用struct,那么它的用户将能够在其中粘贴多个值,而这实际上并不意味着发生。但似乎我也不能使用联盟,因为我不能将boost::gregorian::date对象放入其中。如果我有办法使用union吗?

,有人可以建议

3 个答案:

答案 0 :(得分:5)

使用boost :: variant或boost :: any。当您必须组合非POD时,联盟不是解决方案。

答案 1 :(得分:1)

而不是gregorian :: date,存储一个greg_ymd结构,并使用year_month_day()方法将日期转换为ymd。

答案 2 :(得分:0)

你是说你不能把boost :: gregorian :: date放在union中,因为它是非POD类型的吗? C ++ 0x放宽了这个限制。如果你得到gcc 4.6并使用-std = c ++ 0x构建它,你可以把它放在一个联合中。见这里:http://en.wikipedia.org/wiki/C%2B%2B0x#Unrestricted_unions