C++ Map storing multiple data types

Dear C++ Users,

I am trying to create a generic map container which shell contain data of different datatypes. I already found a solution in this forum here:

http://www.cplusplus.com/forum/general/14982/

Introducing a container with a Base Class as content type and inserting objectes of Derived Class types from that Base Class suites my implementation very well.
But it is not really working. I implemented it this way:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
class MyType                                                                                                                         
{                                                                                                                                    
  public:                                                                                                                            
        MyType() {}                                                                                                                  
        virtual ~MyType() {}                                                                                               
};                                                                                                                                   
                                                                                                                                     
template <class PT> class ParseType : public MyType                                                                                  
{                                                                                                                                    
  public:                                                                                                                            
        ParseType( Parser<PT> cp ) : MyType(),
                content( new Parser<PT>( cp ) ){}
        ~ParserType(){ delete content; }                                                                             
                                                                                                                                     
        PT get_val( int n )                                                                                     
        {                                                                                                                            
                return content->val( n );                                                                                  
        }                                                                                                                            
                                                                                                                     
        Parser<PT>* content;                                                                                                         
                                                                                                                                     
};


Then I insert one element.

1
2
3
4
5

        // index being an object of type Parser<string>
        ParseType<string>* test = new ParseType<string>( index );
        // and index.val(0) = "-n"
        iMap.insert( pair< string, MyType* >( index.id(0), test ) );


Now I think I should be able to call
1
2
3
const string key("-n");

iMap.at(key)->content->val(n);

Or
 
iMap.at(key)->get_val(n);


But neither one compiles with the error that "class MyType" (as the map container is pointing to a MyClass object) has no member/member function "content"/"get_val".
I also tried introducing member and member function "content" and "get_val" in "class MyType", which I thought should be hidden while constructing ParseType<string>. This would compile but it does not call the member "content or member function "get_val" from class ParseType.

A second try was to remove templatization of "class ParseType" and introduce a specific, let's say, "class ParseString" for objects of type Parser<string>. But the problems remain the same either the compiler complains due to missing member/member function or retreiving the map content will not call the derived class member/member function.

Can anyone help, please? Thanks in advance.

Cheers
True, your class MyType does not have PT get_val(int). It could have a pure virtual get_val(int), but the returntype remains a problem.
Yes, I tried that and I tried a templated template <typename T> T get_val(int) in class MyType, whereas I have to construct some functionality to return that type to inside the Base class. In that case I templated the get_val(int) in class ParserType in order to hide the Base member function. But that does not work.

I am really confused. This procedure is proposed in several forums discussing to store data of various data types in a single stl container. For me it does not work.
Last edited on
You could dynamic_cast pointer to derived type. Then you can use the interface of the derived.
No, I wanted to prevent dynamic_casts. Casting in general I want to be the last solution to be considered. But you are right. As it seems casting has to go with it if one tries it with the "Base-class-Derived-class" Ansatz.

I solved it with the boost::variant library also proposed in several threads on this topic. It is actually much more beautiful. Less code and no casting is necessary:

1
2
3
4
5
6
7
typedef boost::variant< boost::shared_ptr< Parser<string> >,
                        boost::shared_ptr< Parser<unsigned> >,
                        boost::shared_ptr< Parser<float> >,
                        boost::shared_ptr< Parser<double> >
                        > FlexParser;

typedef std::map< std::string, FlexParser > FlexMap;


Anyhow thanks for your help!
Registered users can post here. Sign in or register to post.