Search code examples
c++dictionaryboostvariant

(C++, boost::variant) Datatype of boost variant map and performing mathematical operation over it


I have defined the following type of d

typedef boost::variant<string, double> flex_String_Double;
map<string, flex_String_Double> FDParam;

and FDParam is of the following form:

{"setNumber", 3}
{"Money", 3.152}
{"Fight", "No"}

What I wanted to do is (expecting to obtain 6.152):

cout << FDParam["setNumber"] + FDParam["Money"] << endl;

However, this command does not work and gives me the following error:

Invalid operands to binary expression ('std::__1::map<std::__1::basic_string<char>, boost::variant<std::__1::basic_string<char>, double>, std::__1::less<std::__1::basic_string<char> >, std::__1::allocator<std::__1::pair<const std::__1::basic_string<char>, boost::variant<std::__1::basic_string<char>, double> > > >::mapped_type' (aka 'boost::variant<std::__1::basic_string<char>, double>') and 'double')

Can anybody help me to fix this problem?


Solution

  • You have to use boost::get<T> to deduce the type you want to take from the variant...

    #include <iostream>
    #include <map>
    #include <boost/variant.hpp>
    
    typedef boost::variant<std::string, double> flex_String_Double;
    std::map<std::string, flex_String_Double> FDParam;
    
    int main()
    {
        FDParam["setNumber"] = 3;
        FDParam["Money"] = 3.152;
        FDParam["Fight"] = "No";
        std::cout << boost::get<double>(FDParam["setNumber"]) + 
                     boost::get<double>(FDParam["Money"]) << std::endl;
        std::cout << "Can Fight? " << boost::get<std::string>(FDParam["Fight"]) << std::endl;
    }
    

    Edit: Also, this code can be made much shorter if you don't consider using global variables... use references instead if you want any other function to access/modify the variable...

    #include <iostream>
    #include <map>
    #include <boost/variant.hpp>
    
    typedef boost::variant<std::string, double> flex_String_Double;
    
    int main()
    {
        std::map<std::string, flex_String_Double> FDParam = {
            { "setNumber", 3 },
            { "Money", 3.152 },
            { "Fight", "No" },
        };
        std::cout << boost::get<double>(FDParam["setNumber"]) + 
                     boost::get<double>(FDParam["Money"]) << std::endl;
        std::cout << "Can Fight? " << boost::get<std::string>(FDParam["Fight"]) << std::endl;
    }