最近、クラスを実装するとき、ストリーム演算子を追加する演算子という名前のネストされた名前空間を作成します。
これを行うのは、クラスの名前空間 os 以外の名前空間でそれらを使用する必要があることが多いためです。
using my_namespace::operators;
ちょうどいいところに、それだけです。
ここでは、クラス ポイント、クラス セグメント、およびセグメントのストリームがポイントのストリームを呼び出すそれらのストリーム オペレーターの例を示します。しかし...コンパイルできません:
クラスポイント:
#ifndef POINT_HPP
#define POINT_HPP
#include <iostream>
namespace geom {
class Point
{
public:
Point(int x_, int y_) : x(x_), y(y_) {};
int x;
int y;
};
namespace operators {
std::ostream& operator<<(std::ostream& out, const Point& p)
{
out << "(" << p.x << ", " << p.y << ")";
return out;
}
} // ~ namespace geom::operators
} // ~ namespace geom
#endif // ~ POINT_HPP
クラス区分:
#ifndef SEGMENT_HPP
#define SEGMENT_HPP
#include <iostream>
#include "point.hpp"
namespace geom_2d {
class Segment
{
public:
Segment(const geom::Point& a_, const geom::Point& b_) : a(a_), b(b_) {};
geom::Point a;
geom::Point b;
};
namespace operators {
std::ostream& operator<<(std::ostream& out, const Segment& p)
{
using namespace geom::operators;
out << "[" << p.a << ", " << p.b << "]";
return out;
}
} // ~ namespace geom_2d::operators
} // ~ namespace geom_2d
#endif // ~ SEGMENT_HPP
主要:
#include <iostream>
#include "segment.hpp"
#include "point.hpp"
using namespace geom_2d::operators;
int main()
{
geom::Point p1(3, 5);
geom::Point p2(1, 6);
geom_2d::Segment s(p1, p2);
std::cout << s << std::endl;
return 0;
}
これはコンパイルできず、次のようになります。
../segment.hpp:21: error: no match for ‘operator<<’ in ‘std::operator<< [with _Traits = std::char_traits<char>](((std::basic_ostream<char, std::char_traits<char> >&)((std::ostream*)out)), ((const char*)"[")) << p->geom_2d::Segment::a’
名前空間演算子を削除すると正しくコンパイルされますが、先ほど言ったように、それは避けたいと思います。
この問題は、別の名前空間演算子内で名前空間演算子を使用して呼び出すことに関係していると思います。
何か案は?