объединение в C ++ и нестандартные конструируемые объекты - PullRequest
4 голосов
/ 25 ноября 2010

В моей программе есть ситуация, когда мне нужно выполнить некоторое преобразование из строк в различные типы, и, очевидно, результат может быть только одного типа.Поэтому я решил создать 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 ]

5 голосов
/ 25 ноября 2010

Используйте boost :: option или boost :: any. Союз не является решением, когда вам нужно объединить не POD.

1 голос
/ 25 ноября 2010

Вместо gregorian :: date, сохраните структуру greg_ymd и используйте метод year_month_day () для преобразования даты в ymd.

0 голосов
/ 25 ноября 2010

Вы говорите, что не можете добавить в объединение boost :: gregorian :: date, потому что это не POD тип? C ++ 0x ослабляет это ограничение. Если вы получаете gcc 4.6 и собираете его с -std = c ++ 0x, вы можете объединить его. Смотрите здесь: http://en.wikipedia.org/wiki/C%2B%2B0x#Unrestricted_unions.

...