0

This is my container:

std::map<std::string, Node> idents

Node and Variable classes:

class Node {
};

template <class T> class Variable : public  Node {
public:
    T value;
    Variable(T arg) : value(arg) { }
    ~Variable();
};

And I have this function:

void assignment( const char * name, const char * val ) {
    if( identifier_exists( name ) )
        printf( "exist" );
        else {
            try { // Assume `val` is a number
                double num = std::stod( val );
                auto variable = new Variable<double>( num );
                idents.insert( std::pair<std::string, Variable<double>> pair(     std::string( name ), variable ) );
            } catch ( const std::invalid_argument& ) { // It's a string
                  auto variable = new Variable<std::string>( val );
                  idents.insert( std::pair<std::string, Variable<std::string>>  pair( std::string( name ), variable ) );
            }
        }
}

I get this error when compiling:

node.cpp:20:62: error: expected primary-expression before ‘pair’
      idents.insert( std::pair<std::string, Variable<double>> pair(   std::string( name ), variable ) );                                                             
                                                              ^~~~
node.cpp:23:67: error: expected primary-expression before ‘pair’
      idents.insert( std::pair<std::string, Variable<std::string>> pair( std::string( name ), variable ) );                                                        
                                                                   ^~~~

The function has to look if variable already exists (by name) and if not, insert it to the map. The variable class serves as a container for different types of values. Node serves to create the map without instantiating the value to some specialized Variable.

Mario Gil
  • 493
  • 1
  • 5
  • 14
  • 3
    Attempting to fix the compiler error is a waste of time. After the compilation error gets fixed, this code will not work anyway because of [object slicing](http://stackoverflow.com/questions/274626/what-is-object-slicing). The map contains `Node`s. Attempting to insert any subclass of `Node` into the map will flush the subclass down the drain. C++ is not Java. – Sam Varshavchik Jun 11 '16 at 23:35
  • take out the underlined word `pair` . (But read Sam's comment also) – M.M Jun 12 '16 at 02:40
  • Thank you, @SamVarshavchik, I was unaware of _object slicing_. I will look into those fundamental errors. – Mario Gil Jun 12 '16 at 17:08

1 Answers1

3

There are several problems here:

  1. You're trying to insert a pointer (variable = new Variable<....>) and the map doesn't take pointers. You might want std::map<std::string, Node*> idents; instead. By using pointers in the map, you also avoid the object slicing issue you would otherwise face

  2. Your insert should look like idents.insert( std::pair<std::string, Node*>(name, variable ) ); (ie. use a Node pointer and remove the extra pair)

jtlim
  • 3,861
  • 1
  • 16
  • 14
  • Yes, passing a std::pair object was the right way, I used `make_pair`. Also am using `Node*` now, but I suspect that `Variable`'s values won't be accessible if they aren't inherited from `Node` because `Variable` would be treated as `Node`. Anyway, thank you. – Mario Gil Jun 12 '16 at 17:05
  • There are a few of ways that you can access Variable's values: 1. Create virtual accessor functions in the base class. This will require specific overriding in the Variable subclasses. 2. If you know exactly what kind of Variable* you have, you can just force a type cast. 3. You can use dynamic_cast to test, or implement you own system of RTTI – jtlim Jun 14 '16 at 07:53