Home > Software design >  Syntax error on my member initializer lists
Syntax error on my member initializer lists

Time:02-03

I have the following class:

class MathNode {
  protected:
  std::list<std::pair<std::string, MathNode*> > myChildren;
 
  public:
  MathNode()
    : myChildren{} // line 15
  {} // line 16
  MathNode(std::string l, MathNode* c)
    : myChildren{ std::make_pair(l, c) }
  {}
  MathNode(std::string l1, MathNode* c1,
           std::string l2, MathNode* c2)
    : myChildren{ std::make_pair(l1, c1),
                  std::make_pair(l2, c2) }
  {}
};

And when I go to compile I get the following errors:

In file included from ./calc.hpp:6:
./nodes.hpp:16:9: error: expected member name or ';' after declaration
      specifiers
        {}
        ^
./nodes.hpp:15:25: error: expected '('
            : myChildren{}

I tried changing the curlies to parenthesis on line 15, and got these errors:

In file included from ./calc.hpp:6:
./nodes.hpp:19:9: error: expected member name or ';' after declaration
      specifiers
        {}
        ^
./nodes.hpp:18:25: error: expected '('
            : myChildren{ std::make_pair(l, c) }
                        ^
./nodes.hpp:18:47: error: expected ';' after expression
            : myChildren{ std::make_pair(l, c) }

As far as I can tell, I'm using perfectly legal C 11 syntax, and I even explicitly passed the option to use C 11 in my Makefile. What gives?

EDIT: We've narrowed down the issue to a Makefile problem. Here's the Makefile:

all: calc test

calc: parser.o lexer.o calc.o
    g   -std=c  11 -g -o calc calc.o lexer.o parser.o

test: calc
    ./calc input.txt

%.o: %.cpp
    g   -std=c  11 -g -c $<

lexer.o: lexer.yy.cc
    g   -std=c  11 -g -c $< -o lexer.o

lexer.yy.cc: grammar.hh lexer.l
    flex --outfile lexer.yy.cc lexer.l

grammar.hh: parser.yy
    bison --defines=grammar.hh -d -v parser.yy

parser.cc: grammar.hh

.PHONY: clean test

clean:
    rm -rf *.o *.cc *.hh calc parser.output

EDIT: I solved this in an answer below.

CodePudding user response:

std::list has its own default constructor, so your default constructor does not need to explicitly initialize myChildren at all, eg:

MathNode() {}

Or, in C 11 and later:

MathNode() = default;

In your other constructors, you need C 11 or later to use the initialization syntax you want. As you deduced, you are not compiling for C 11, which is why you are getting errors on C 11 syntax. You need to fix your makefile to enable C 11 properly.

Otherwise, just use push_back() inside the constructor bodies instead, eg:

MathNode(std::string l, MathNode* c)
{
    myChildren.push_back( std::make_pair(l, c) );
}

MathNode(std::string l1, MathNode* c1,
         std::string l2, MathNode* c2)
{
    myChildren.push_back( std::make_pair(l1, c1) );
    myChildren.push_back( std::make_pair(l2, c2) );
}

CodePudding user response:

The solution was to add a rule for parser.o to compile parser.cc:

parser.o: parser.cc
    g   -std=c  11 -g -c $< -o parser.o
  •  Tags:  
  • Related