Last active
November 5, 2018 20:25
-
-
Save jflopezfernandez/a775e2ee092b4c76a14c749881ba936b to your computer and use it in GitHub Desktop.
Defining an output operator for a user-defined type
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <cstdlib> | |
#include <iostream> | |
#include <sstream> | |
#include <string> | |
#include <vector> | |
namespace IO | |
{ | |
template <typename CharT, typename Traits = std::char_traits<CharT>> | |
std::basic_ostream<CharT, Traits>& | |
endl (std::basic_ostream<CharT, Traits>& outputStream) | |
{ | |
return outputStream << outputStream.widen('\n'); | |
} | |
} | |
class Book { | |
std::string m_title; | |
std::string m_author; | |
unsigned int m_isbn; | |
std::string m_genre; | |
public: | |
Book() | |
: m_title("Untitled"), m_author("Unknown"), m_isbn(0), m_genre("Unknown") | |
{ } | |
Book(const std::string& title, const std::string& author, const unsigned int isbn, const std::string& genre) | |
: m_title(title), m_author(author), m_isbn(isbn), m_genre(genre) | |
{ } | |
std::string title() const noexcept { return m_title; } | |
std::string author() const noexcept { return m_author; } | |
unsigned int ISBN() const noexcept { return m_isbn; } | |
std::string genre() const noexcept { return m_genre; } | |
void setTitle(const std::string& title) { m_title = title; } | |
void setAuthor(const std::string& author) { m_author = author; } | |
void setISBN(const unsigned int isbn) { m_isbn = isbn; } | |
void setGenre(const std::string& genre) { m_genre = genre; } | |
}; | |
// This is the traditional output operator implementation most programmers | |
// use. There are two problems with this. First, because `ostream` is used | |
// in the signature, the function applies only to streams with the character | |
// type `char`. If the function is intended only for use in Western Europe or | |
// in North America, this is no problem. On the other hand, a more general | |
// version requires only a little extra work, so it should at least be | |
// considered. | |
// | |
// Another problem arises if a field width is set. In this case, the result is | |
// probably not what might be expected. The field width applies to the | |
// immediately following write. | |
// | |
// Source: The C++ Standard Library, Josuttis (2011) [page. 810-811] | |
//inline | |
//std::ostream& operator<<(std::ostream& outputStream, const Book& book) | |
//{ | |
// outputStream << "Title: " << book.title() << IO::endl; | |
// outputStream << "Author: " << book.author() << IO::endl; | |
// outputStream << "ISBN: " << book.ISBN() << IO::endl; | |
// outputStream << "Genre: " << book.genre() << IO::endl; | |
// | |
// return outputStream; | |
//} | |
template <typename T, typename Traits> | |
inline | |
std::basic_ostream<T, Traits>& | |
operator<<(std::basic_ostream<T, Traits>& outputStream, | |
const Book& book) | |
{ | |
// String stream with the same format, without the | |
// special field width | |
std::basic_ostringstream<T, Traits> s; | |
s.copyfmt(outputStream); | |
s.width(0); | |
// Fill String Stream | |
outputStream << "Title: " << book.title() << IO::endl; | |
outputStream << "Author: " << book.author() << IO::endl; | |
outputStream << "ISBN: " << book.ISBN() << IO::endl; | |
outputStream << "Genre: " << book.genre() << IO::endl; | |
// Print String Stream | |
outputStream << s.str(); | |
return outputStream; | |
} | |
int main() | |
{ | |
Book b1 { "The C++ Standard Library", "Nicolas Josuttis", 1, "Computer Science" }; | |
Book b2 { "Little Red Riding Hood", "The Brothers Grimm", 2, "Fairytales" }; | |
Book b3 { "Mastery", "George Leonard", 3, "Self-Improvement" }; | |
const std::vector<Book> books = { b1, b2, b3 }; | |
for (const auto& book : books) | |
{ | |
std::cout << book << IO::endl; | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment