This is a follow-up on this Q&A. I now have several data structures in a namespace ast
, subdivided over two sub-namespaces (algebraic
and numeric
) that correspond to the two different formats that the grammar recognizes.
namespace ast {
namespace algebraic {
struct occupance
{
char pc;
char col;
int row;
};
using pieces = std::vector<occupance>;
struct placement
{
char c;
boost::optional<pieces> p;
};
}
namespace numeric {
struct occupance
{
char pc;
int sq;
};
struct range
{
occupance oc;
int sq;
};
using pieces = std::vector<boost::variant<range, occupance>>;
struct placement
{
char c;
boost::optional<pieces> p;
};
}
struct fen
{
char c;
std::vector<boost::variant<numeric::placement, algebraic::placement>> p;
};
}
Working parser Live On Coliru
The trouble starts when I try to define streaming operators for the various types. With the generic operator<<
taking a vector<T>
in the same namespace as the various ast
structs (as in the linked Q&A), all is fine. But once I have two sub-namespaces algebraic
and numeric
and define the various operators in these namespaces:
namespace ast {
template <typename T>
std::ostream& operator<<(std::ostream& os, std::vector<T> const& v)
{
os << "{";
for (auto const& el : v)
os << el << " ";
return os << "}";
}
namespace algebraic {
std::ostream& operator<<(std::ostream& os, occupance const& oc)
{
return os << oc.pc << oc.col << oc.row;
}
std::ostream& operator<<(std::ostream& os, placement const& p)
{
return os << p.c << " " << p.p;
}
} // algebriac
namespace numeric {
std::ostream& operator<<(std::ostream& os, occupance const& oc)
{
return os << oc.pc << oc.sq;
}
std::ostream& operator<<(std::ostream& os, range const& r)
{
for (auto sq = r.oc.sq; sq <= r.sq; ++sq)
os << r.oc.pc << sq << " ";
return os;
}
std::ostream& operator<<(std::ostream& os, placement const& p)
{
return os << p.c << " " << p.p;
}
} // numeric
} // ast
Live On Coliru the appropriate operators are no longer being found.
In file included from main.cpp:4:
/usr/local/include/boost/optional/optional_io.hpp:47:21: error: invalid operands to binary expression ('basic_ostream<char, std::__1::char_traits<char> >' and 'const std::__1::vector<ast::algebraic::occupance, std::__1::allocator<ast::algebraic::occupance> >')
else out << ' ' << *v ;
~~~~~~~~~~ ^ ~~
main.cpp:79:37: note: in instantiation of function template specialization 'boost::operator<<<char, std::__1::char_traits<char>, std::__1::vector<ast::algebraic::occupance, std::__1::allocator<ast::algebraic::occupance> > >' requested here
return os << p.c << " " << p.p;
Question: how to define the various streaming operators to properly print the matched AST?