7

how can I insert my own class objects into ptr_map from boost. The objects are templated so I can't use some static typename in the map. So I did:

ptr_map<string, any> someMap;

My class inherits the boost::noncopyable.

someMap.insert("Test", new MyClass<SomeTemplate>());

The error is: error: no matching function for call to ‘boost::ptr_map.


UPD: I'd prefer to make some wrapper and don't use the boost::any. So:

class IWrapper { };
class MyClass : public IWrapper { };

ptr_map<string, IWrapper> someMap;
someMap.insert("Test", new MyClass<SomeTemplate>());

Why it won't work (the same error)? I could pass the inherited class into parent interface. What's wrong?

manlio
  • 18,345
  • 14
  • 76
  • 126
Max Frai
  • 61,946
  • 78
  • 197
  • 306

2 Answers2

3

By far, most of the time problems of this type ought to be solved with a common base class. This is the case when all of the classes will be used similarly. Runtime polymorphism.

I have seen legitimate reasons to not allow a common base class. In this case boost::variant will generally server better as there are still methods to treat each item uniformly (a visitor). Compile time polymorphism.

I have never seen a legitimate use for for boost::any. I'm not saying there isn't one, but it is so rare that I've never encountered it.


That said, try this.

std::map<std::string,boost::any> someMap;
boost::any insanity = new MyClass<SomeTemplate>;
someMap.insert("Test",insanity);

or

boost::ptr_map<std::string,boost::any> someMap;
boost::any* ive_lost_it = new boost::any( new MyClass<SomeTemplate> );
someMap.insert("Test", ive_lost_it );
deft_code
  • 57,255
  • 29
  • 141
  • 224
  • My clas is templated. I've updated the sample. I can't make some base for it (without template). – Max Frai Jun 17 '10 at 15:05
  • Okay, thanks. The way with any should work. But could you look at new update of code? I tried to realize your first idea. – Max Frai Jun 17 '10 at 15:21
1

First you must provide any* to your ptr_map.
Then the key must be an lvalue (due to exception-safety issues).

boost::ptr_map<std::string, any> someMap;
any * p = new any(MyClass<Sometype>);
std::string test = "test";
someMap.insert(test, p);

-- edit
Same thing if you are using a wrapper class. the key must be an lvalue.

By the way the problem with the wrapper/base class here is that you won't be able to get back to the original type (and you don't have dynamic polymorphism either because of template type).

log0
  • 10,489
  • 4
  • 28
  • 62
  • lvalue means assignable (and not const). "test" is non-assignable and const, std::string test however is an lvalue. – log0 Jun 17 '10 at 16:00