Search code examples
c++boostreturn-typeboost-any

single get method which return different type variables


I want to make a class that will have a single get template method which will receive an std::string to find in a std::map the right variable and return it.

The std::map should store any type of variable, so I used boost::any, so far the std::map looks like that:

std::map<std::string, boost::any> variables_;

for the get function, I tried something like that:

template <typename T>
T get(std::string& parameter)
{
    return variables_[parameter];
}

But no lucky, my question is, is that even possible to do? If so, how?

The basic idea is that I dont want to make an specific method to every specific variable in my class, so other classes dont need to know about every get method of it.

Thanks!

ps: For anyone asking why I want this, here is a resume of it, I have a lot of algorithms, that will run in a certain order, and it will use that for the last one already runned algorithm. So, what I want is to make an xml file, that will tell what algorithms will run, in which order and what data it will use from another algorithm.

So, for example, algorithm A have an variable named "threshold", algorithm B need that information, so, normally it will have to ask it from the A using something like A.getThreshold, but as far as I know, I can't call a object function with it name in an string (from the xml file), so my solution would be have only an get function which i pass the variable name I want and that function will return it to me.


Solution

  • An alternative solution would be to "wrap" the boost::any object into another object which can be automatically converted to anything you want. I don't think it's a good practice but it's the best fit according to your question.

    class AnyWrapper {
        boost::any value;
    public:
        AnyWrapper(const boost::any& val) : value(val) {}
        template<typename T> operator T() {
            return boost::any_cast<T>(value);
        }
    }
    

    And your getter would be something like :

    AnyWrapper get(std::string& parameter)
    {
        return variables_[parameter];   // variables is a std::map<std::string, boost::any> 
    }
    

    And then you should be able to retrieve your elements like that :

    int integerValue = myContainer.get("age");
    std::string stringValue = myContainer.get("name");
    

    But again, this is not a clean solution. There is a reason why the boost authors chose to make the any_cast explicit :)