これは、この Q&Aのフォローアップです。文法が認識する 2 つの異なる形式に対応するnamespace ast
2 つのサブ名前空間 (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
さまざまなタイプのストリーミング演算子を定義しようとすると、問題が発生します。(リンクされた Q&A のように)さまざまな構造体と同じ名前空間でジェネリックoperator<<
を使用すると、すべて問題ありません。しかし、2 つのサブ名前空間があり、これらの名前空間でさまざまな演算子を定義すると、次のようになります。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 を適切に出力するために、さまざまなストリーミング オペレーターを定義する方法を教えてください。