views:

199

answers:

2
+3  Q: 

Boost any usage

Hello, 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?

+2  A: 

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 );
caspin
My clas is templated. I've updated the sample. I can't make some base for it (without template).
Ockonal
Okay, thanks. The way with any should work. But could you look at new update of code? I tried to realize your first idea.
Ockonal
+1  A: 

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).

Ugo
What does 'lvalue' mean? Could you show some sample?
Ockonal
lvalue means assignable (and not const). "test" is non-assignable and const, std::string test however is an lvalue.
Ugo