正直なところ、なぜこれが必要なのかわかりませんが、これはある種の演習または宿題だと思います。とにかく、この機能の実装に関連する微妙な点がいくつかありますが、それを自分で理解することはできないと思われるので、ここに実際の解決策を示します。
人
#include <iostream>
#include <sstream>
class Person {
public:
void process() {
// Let's see what we've got in `_request`
std::cout << _request.rdbuf() << std::endl;
// Do some processing to produce correponding _response
// In this example we hardcode the response
_response << "I'm fine, thanks!";
}
private:
std::stringstream _request;
std::stringstream _response;
// Make them all friends so that they can access `_request` and `_response`
friend Person& operator<<(Person& p, std::string const& s);
friend Person& operator<<(Person& p, std::ostream& (*f)(std::ostream&));
friend std::ostream& operator<<(std::ostream &o, Person& p);
friend Person& operator>>(Person& p, std::string& s);
};
Person& operator<<(Person& p, const std::string& s) {
p._request << s;
return p;
}
// Notice this peculiar signature, it is required to support `std::endl`
Person& operator<<(Person& p, std::ostream& (*f)(std::ostream&)) {
p._request << f;
return p;
}
// Somewhat conventional stream operator overload (in terms of signature)
std::ostream& operator<<(std::ostream &o, Person& p) {
o << p._response.rdbuf();
return o;
}
Person& operator>>(Person& p, std::string& s) {
// NOTE: This will read not the whole `_reponse` to `s`, but will stop on
// the first whitespace. This is the default behavior of `>>` operator of
// `std::stringstream`.
p._response >> s;
return p;
}
達成しようとしている機能に関して、最初の試みは完全に間違っていることに注意してください。これは、ストリーム演算子のオーバーロードに関する従来のチュートリアルに従っているように見えるという事実に要約されますが、ここでは、目的の機能を実現するためにアプローチが異なる必要があります。特に、提案されたストリーム演算子のオーバーロードのシグネチャに注意してください。
さらに、たとえば などの他の入力タイプをサポートするには、オーバーロードを追加する必要がありますint
。基本的に、標準でstd::basic_ostreamが提供するものと同様のオーバーロードを追加する必要があります。特に、最後のものに注意してください。
basic_ostream& operator<<(basic_ostream& st,
std::basic_ostream& (*func)(std::basic_ostream&));
この男はサポートするためにそこにいstd::endl
ます。Person
適切に機能するように、同様のオーバーロードを既に追加していることに注意してstd::endl
ください (以下を参照)。プリミティブ型のようなその他のオーバーロードは、演習として残されています。
応答の読み取り
あなたが最初に欲しかったもの。
int main() {
Person daniel;
daniel << "Hello" << std::endl;
daniel << "How " << "are you";
daniel << " doing?" << std::endl;
// We are ready to process the request so do it
daniel.process();
// And Daniel's answer is...
std::cout << "Daniel says: " << daniel << std::endl;
return 0;
}
応答を読む: 別の方法
これはやや不器用で面倒ですが、基本的にはPerson& operator>>(Person& p, std::string& s)
オーバーロードの実装のコメントの結果です (上記を参照)。
int main() {
Person daniel;
daniel << "Hello" << std::endl;
daniel << "How " << "are you";
daniel << " doing?" << std::endl;
// We are ready to process the request so do it
daniel.process();
// And Daniel's answer is...
std::string part1;
std::string part2;
std::string part3;
// Will read "I'm"
daniel >> part1;
// Will read "fine,"
daniel >> part2;
// Will read "thanks!"
daniel >> part3;
std::cout << "Daniel says: " << part1 << " " << part2 << " " << part3 << std::endl;
return 0;
}