这是本问答的后续内容。我现在在 a 中有几个数据结构namespace ast
,细分为两个子命名空间(algebraic
和numeric
),它们对应于语法识别的两种不同格式。
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;
};
}
工作解析器Live On Coliru
当我尝试为各种类型定义流式操作符时,麻烦就开始了。由于泛型operator<<
采用vector<T>
与各种结构相同的命名空间ast
(如在链接的问答中),一切都很好。但是一旦我有两个子命名空间algebraic
并numeric
在这些命名空间中定义各种运算符:
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不再找到合适的运算符。
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;
问题:如何定义各种流操作符以正确打印匹配的 AST?