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
