次の例は正常にコンパイルされますが、operator<<() の宣言と定義を分離する方法がわかりません。これはこの特定のケースです。
定義を分割しようとするたびに、友人が問題を引き起こし、gcc は operator<<() 定義が正確に 1 つの引数を取る必要があると不平を言います。
#include <iostream>
template <typename T>
class Test {
public:
Test(const T& value) : value_(value) {}
template <typename STREAM>
friend STREAM& operator<<(STREAM& os, const Test<T>& rhs) {
os << rhs.value_;
return os;
}
private:
T value_;
};
int main() {
std::cout << Test<int>(5) << std::endl;
}
Operator<<() には、さまざまな種類の出力ストリーム (std::cout、std::wcout、または boost::asio::ip::tcp::iostream) で動作する自由な最初のパラメーターがあるはずです。2 番目のパラメーターは、周囲のクラスの特殊なバージョンにバインドする必要があります。
Test<int> x;
some_other_class y;
std::cout << x; // works
boost::asio::ip::tcp::iostream << x; // works
std::cout << y; // doesn't work
boost::asio::ip::tcp::iostream << y; // works
その上、非メンバー関数を使用することは、非メンバー関数がクラスのプライベート属性にアクセスできないため、定義と宣言を分割することと同等ではありません。