#include #include #include #include class Sink { public: template void put(const T& value) { std::ostringstream stream; stream << value; if (!stream) throw std::runtime_error("conversion failed"); write(stream.str()); } virtual ~Sink() = default; private: virtual void write(const std::string& text) = 0; }; class Buffer final : public Sink { std::string data_; void write(const std::string& text) override { data_ += text; } public: const std::string& data() const { return data_; } }; int main() { Buffer buffer; Sink& sink = buffer; sink.put(12); sink.put(" apples"); assert(buffer.data() == "12 apples"); }