views:

84

answers:

2

Hello, I'm writing statistic system. It should make some output with given params. For example:

float getSunActivity() { ... }
int getEarthActivity() { ... }

StatisticSystem::track("sun_activity", boost::any(getSunActivity()));
StatisticSystem::track("earth_activity", boost::any(getEarthActivity()));

class StatisticSystem
{
   typedef std::map<string, const boost::any*> stats;
   stats mStatsData;

   static void track(const string &name, const boost::any &param);
   void update();
};

StaticSystem::track(const string &name, const boost::any &param)
{
   mStatsData[name] = &param;
}

StaticSystem::update()
{
    BOOST_FOREACH(stats::value_type &row, mStatsData)
    {
        string data = lexical_cast<string>(&row.second);
        cout << data << "\n";
        // Usage of 'data' value
    }
}

Look, each update calling I need in the new value of all passed variables. So I decided to pass their addresses in the memory. But now the data consist of address. How can I receive value from it? Is it possible, if not, what could you advice for this problem?

A: 

Data stored at an address is retrieved by unary operator*.

In your code, you should have used *row.second to get the value, rather than the address of second.

All this code looks peculiar though. The address manipulation technique is rather questionable, IMO.

Pavel Radzivilovsky
A: 

I suggest not using BOOST_FOREACH in this case as it might be somewhat harder for the reader of the code what's going on under the hood. You can rewrite the update function using plain iterators:

void StaticSystem::update()
{
    for (stats::iterator it = mStatsData.begin(); it != mStatsData.end(); ++it)
    {
        string data = lexical_cast<string>(*it->second);
        cout << data << "\n";
        // Usage of 'data' value
    }
}

However, this alone won't make your code work. There are some other bugs/bad design:
1) Do not use boost::any unless completely necessary - it's a heavy template class that slows down the compilation and gives no hint what actual types are stored inside. A better approach would be creating classes EarthActivity and SunActivity that would both derive from a common class Activity and then use Activity* instead of boost::any* as the map parameter. In case the returned values are only primitive ones (like the float and int in your example), why does Sun return float and Earth int? You should use float/double for both.

2) You are accessing a member of the class StatisticSystem inside the static method track, this is invalid and will not compile. If you are trying to implement a Singleton pattern, there are a lot of tutorials on how to make it correctly, for instance this one: http://www.yolinux.com/TUTORIALS/C++Singleton.html

3) You are missing return types of the functions. If you want the functions to return nothing, specify void as their return type:

void functionReturningNothing() { /* ... */ }
dark_charlie
At whoever: why the negative vote? Please add a comment with a description of the flaws in my post, thanks.
dark_charlie