c++c++11boost-any

Can I avoid all this multiples try/catch


I have a vector of many boost::any In this vector I need to perform some operations on std::vector and on the elements of type IContainer

class   IContainer
{
public:
  virtual ~IContainer(){}
  virtual const boost::any operator[](std::string) const = 0;
};

class   AContainer : public IContainer
{
  std::vector<int>      vect_;
  std::string name_;
public:
  AContainer() : vect_({0, 1, 2, 3, 4, 5}), name_("AContainer") {}
  virtual const boost::any operator[](std::string key) const
  {
    if (key == "str")
      return (name_);
    if (key == "vect")
      return (vect_);
    return nullptr;
  }
};

So I have done the following function (imo quite ugly) but who works correctly

m is const std::vector<boost::any>&

for (const auto & elem : m)
    {
      try
        {
          std::vector<int> v = boost::any_cast<std::vector<int>>(elem);
          display(v);
        }
      catch(boost::bad_any_cast){}
      try
        {
          std::vector<IContainer*> v = boost::any_cast<std::vector<IContainer*>>(elem);
          display(v);
        }
      catch(boost::bad_any_cast){}
      try
        {
          AContainer v(boost::any_cast<AContainer>(elem));
          try
            {
              display(boost::any_cast<const std::vector<int>>(v["vect"]));
            }
          catch (boost::bad_any_cast){}
          try
            {
              std::cout << boost::any_cast<const std::string>(v["str"]) << std::endl;
            }
          catch (boost::bad_any_cast){}
          try
            {
              display(boost::any_cast<std::vector<int> >(v));
            }
          catch (boost::bad_any_cast) {}
        }
      catch(boost::bad_any_cast){}
    }

I have tried to add many "try{}try{}catch{}" but it's not working

Do you have any solutions better than what I have done

Edit

I have tried the solutions of James Kanze, user1131467 and Praetorian

So the 3 are working nicely, but when I have calculate the time of execution, the answer of user1131467 is a bit faster than the other. I must now find a solution to store each types in a map to avoid all this if/else

I will also take a look at boost::variant


Solution

  • Using the pointer-form of any_cast is much cleaner, as it uses the nullability of pointers:

    for (const auto & elem : m)
        if (T1* p = any_cast<T1>(&elem))
        {
             do stuff with *p;
        }
        else if (T2* p = any_cast<T2>(&elem))
        {
             do stuff with *p;
        }
        else if (...)
        {
             ...
        }
    

    This also has the advantage of doing the cast once per case.