Using operator overloading in C++ - c++

class A
{
public:
ostream& operator<<(int string)
{
cout << "In Overloaded function1\n";
cout << string << endl;
}
};
main()
{
int temp1 = 5;
char str = 'c';
float p= 2.22;
A a;
(a<<temp1);
(a<<str);
(a<<p);
(a<<"value of p=" << 5);
}
I want the output to be: value of p=5
What changes should is do...and the function should accept all data type that is passed

There are 2 solutions.
First solution is to make it a template.
template <typename T>
ostream& operator<<(const T& input) const
{
cout << "In Overloaded function1\n";
return (cout << input << endl);
}
However, this will make the a << str and a << p print c and 2.22, which is different from your original code. that output 99 and 2.
The second solution is simply add an overloaded function for const char*:
ostream& operator<<(int string)
{
cout << "In Overloaded function1\n";
return (cout << string << endl);
}
ostream& operator<<(const char* string)
{
cout << "In Overloaded function1\n";
return (cout << string << endl);
}
This allows C strings and everything convertible to int to be A <<'ed, but that's all — it won't "accept all data type that is passed".
BTW, you have forgotten to return the ostream.

Related

How to create a function to be used in an std::ostream or std::cout

Is there a way to create a function which you can use between two << operators in an ostream?
Let's assume the function's name is usd, and might look something like:
std::ostream& usd(std::ostream& os, int value) {
os << "$" << value << " USD";
return os;
}
Then I would like to use it like:
int a = 5;
std::cout << "You have: " << usd(a) << std::endl;
Which would print:
You have: $5 USD
I would prefer a solution without the need for a class.
If you must use a class I would prefer not to mention the class at all when using the usd function. (For example how the std::setw function works)
EDIT:
In my implementation I intend to use the std::hex function, the one described above was just a simplified example but probably shouldn't have.
std::ostream& hex(std::ostream& os, int value) {
os << "Hex: " << std::hex << value;
return os;
}
So I am not sure if a function returning a simple string is sufficient.
To obtain the usage you described:
int a = 5;
std::cout << "You have: " << usd(a) << std::endl;
You'd simply need usd(a) to return something that you have an ostream<< operator for, like a std::string, and no custom ostream<< operator is needed.
For example:
std::string usd(int amount)
{
return "$" + std::to_string(amount) + " USD";
}
You can write other functions to print in other currencies, or to convert between them, etc but if all you want to handle is USD, this would be sufficient.
If you used a class representing money, you could write an ostream<< for that class and you wouldn't need to call a function at all (given that your default ostream<< prints USD)
class Money
{
int amount;
};
std::ostream& usd(std::ostream& os, Money value) {
os << "$" << value.amount << " USD";
return os;
}
int main(int argc, char** argv)
{
Money a{5};
std::cout << "You have: " << a << std::endl; // Prints "You have: $5 USD"
return 0;
}
I don't know how to do this without a class. However, it is easy to do with a class.
struct usd {
int value;
constexpr usd(int val) noexcept : value(val) {}
};
std::ostream& operator<<(std::ostream& os, usd value) {
os << "$" << value.value << " USD";
return os;
}
for hex
struct hex {
int value;
constexpr hex(int val) noexcept : value(val) {}
};
std::ostream& operator<<(std::ostream& os, hex value) {
os << "Hex: " << std::hex << value.value;
return os;
}
usage
int a = 5;
std::cout << "You have: " << usd(a) << std::endl;
std::cout << "You have: " << hex(a) << std::endl;

How to add a custom prefix in a << operator for a custom object

Is there a way to add a custom prefix in the operator<< for an object that I implement?
Ex:
class A {
public:
std::string id;
int count;
};
std::ostream &operator<<(std::ostream &os, const A &a)
{
os << os.prefix() << "Id: " << a.id << "\n";
os << os.prefix() << "Count: " << a.count << "\n";
return os;
}
If I do something like this:
A a;
a.id = "foo";
a.count = 1;
std::cout << a << std::endl;
The output will be:
Id: foo
Count: 1
I want to do something like:
std::cout << set_prefix(" -") << a << std::endl;
std::cout << set_prefix("==>") << a << std::endl;
To get an output like this:
-Id: foo
-Count: 1
==>Id: foo
==>Count: 1
A suggestion is to use std::setfill and os.fill, but std::setfill takes a single char as an argument and I need a custom string instead.
Solution
Looking at operator<<(std::basic_ostream) documentation, I found this:
Before insertion, first, all characters are widened using
os.widen(), then padding is determined as follows: if the number of
characters to insert is less than os.width(), then enough copies of
os.fill() are added to the character sequence to make its length
equal os.width(). If (out.flags()&std::ios_base::adjustfield) ==
std::ios_base::left, the fill characters are added at the end of the
output sequence, otherwise they are added before the output sequence.
After insertion, width(0) is called to cancel the effects of
std::setw, if any.
So the solution that works for me was save the original width of stream at the beggining and than recovering them when necessary.
std::ostream &operator<<(std::ostream &os, const A &a)
{
auto w = os.width();
os << std::setw(w) << "" << "Id: " << a.id << "\n";
os << std::setw(w) << "" << "Count: " << a.count;
return os;
}
Then:
std::cout << a << std::endl;
std::cout << std::setw(4) << a << std::endl;
std::cout << std::setfill('>') << std::setw(2) << a << std::endl;
Gave the following output:
Id: foo
Count: 1
Id: foo
Count: 1
>>Id: foo
>>Count: 1
Maybe a bit of overkill, but you can use something like this:
#include <iostream>
#include <sstream>
struct line_buffered_stream {
std::ostream& out;
std::stringstream ss;
std::string prefix;
line_buffered_stream(std::ostream& out,std::string prefix) :
out(out),prefix(prefix) {}
template <typename T>
auto operator<<(const T& t) -> decltype(this->ss << t,*this) {
ss << t;
return *this;
}
~line_buffered_stream(){
std::string line;
while (std::getline(ss,line)){
out << prefix << line << "\n";
}
}
};
int main() {
line_buffered_stream(std::cout,"==>") << "a\nb\n";
line_buffered_stream(std::cout,"-->") << "a\nb\n";
}
output:
==>a
==>b
-->a
-->b
Live Demo
Note that the implementation above is not meant to be used as anything else than a temporary whose lifetime is restricted to a single line of code. If you dont like that you'd have to add some mechanism to flush the stream to std::cout not to wait till the destructor is called.
I do not know of any way to do this with a string, but if you are content with just a char, it looks like you can use std::setfill manipulator, and than in your overload use the fill character:
std::cout << std::setfill('-') << a << std::endl;
std::ostream &operator<<(std::ostream &os, const A &a)
{
os << os.fill() << "Id: " << a.id << "\n";
os << os.fill() << "Count: " << a.count << "\n";
return os;
}
I'm not a big fan of this because it uses a global variable but that does allow you to have other classes use this same method, they just have to write thier own operator << correctly. It also requires that you call set_prefix(""); when you want to clear the prefix from printing. That said it does allow you to prepend any string you want to the output.
namespace details
{
// we neeed this for tag dispatch
struct Prefix {};
// this will be used in the class(es) operator << for the line prefix
std::string prefix;
// allows set_prefix to be called in the output stream by eating it return and returning the stream as is
std::ostream& operator <<(std::ostream& os, const Prefix& prefix)
{
return os;
}
}
// set the prefix and return a type that allows this to be placed in the output stream
details::Prefix set_prefix(const std::string& prefix)
{
details::prefix = prefix;
return {};
}
class A {
public:
std::string id;
int count;
};
std::ostream &operator<<(std::ostream &os, const A &a)
{
os << details::prefix << "Id: " << a.id << "\n";
os << details::prefix << "Count: " << a.count << "\n";
return os;
}
int main()
{
A a;
a.id = "foo";
a.count = 1;
std::cout << a << std::endl;
std::cout << set_prefix(" -") << a << std::endl;
std::cout << set_prefix("==>") << a << std::endl;
}
Output:
Id: foo
Count: 1
-Id: foo
-Count: 1
==>Id: foo
==>Count: 1
There is a way to store custom data on a stream object, but it isn't pretty: the iword and pword interfaces.
stream_prefix.hpp:
#ifndef STREAM_PREFIX_HPP_
#define STREAM_PREFIX_HPP_
#include <utility>
#include <string>
#include <ostream>
namespace stream_prefix_details {
class set_prefix_helper {
public:
explicit set_prefix_helper(std::string prefix)
: m_prefix(std::move(prefix)) {}
private:
std::string m_prefix;
// These insertion operators can be found by Argument-Dependent Lookup.
friend std::ostream& operator<<(
std::ostream&, set_prefix_helper&&);
friend std::ostream& operator<<(
std::ostream&, const set_prefix_helper&);
};
}
// The set_prefix manipulator. Can be used as (os << set_prefix(str)).
inline auto set_prefix(std::string prefix)
-> stream_prefix_details::set_prefix_helper
{ return stream_prefix_details::set_prefix_helper{ std::move(prefix) }; }
// Get the prefix previously stored by (os << set_prefix(str)), or
// an empty string if none was set.
const std::string& get_prefix(std::ostream&);
#endif
stream_prefix.cpp:
#include <stream_prefix.hpp>
namespace stream_prefix_details {
int pword_index() {
static const int index = std::ios_base::xalloc();
return index;
}
void stream_callback(std::ios_base::event evt_type,
std::ios_base& ios, int)
{
if (evt_type == std::ios_base::erase_event) {
// The stream is being destroyed, or is about to copy data
// from another stream. Destroy the prefix, if it has one.
void*& pword_ptr = ios.pword(pword_index());
if (pword_ptr) {
delete static_cast<std::string*>(pword_ptr);
pword_ptr = nullptr;
}
} else if (evt_type == std::ios_base::copyfmt_event) {
// The stream just copied data from another stream.
// Make sure we don't have two streams owning the same
// prefix string.
void*& pword_ptr = ios.pword(pword_index());
if (pword_ptr)
pword_ptr =
new std::string(*static_cast<std::string*>(pword_ptr));
}
// Can ignore imbue_event events.
}
std::ostream& operator<<(std::ostream& os,
set_prefix_helper&& prefix_helper)
{
void*& pword_ptr = os.pword(pword_index());
if (pword_ptr)
*static_cast<std::string*>(pword_ptr) =
std::move(prefix_helper.m_prefix);
else {
os.register_callback(stream_callback, 0);
pword_ptr = new std::string(std::move(prefix_helper.m_prefix));
}
return os;
}
std::ostream& operator<<(std::ostream& os,
const set_prefix_helper& prefix_helper)
{
void*& pword_ptr = os.pword(pword_index());
if (pword_ptr)
*static_cast<std::string*>(pword_ptr) = prefix_helper.m_prefix;
else {
os.register_callback(stream_callback, 0);
pword_ptr = new std::string(prefix_helper.m_prefix);
}
return os;
}
}
const std::string& get_prefix(std::ostream& os)
{
void* pword_ptr = os.pword(stream_prefix_details::pword_index());
if (pword_ptr)
return *static_cast<std::string*>(pword_ptr);
else {
// This string will never be destroyed, but it's just one object.
// This avoids the Static Destruction Order Fiasco.
static const std::string* const empty_str = new const std::string;
return *empty_str;
}
}
Usage:
#include <iostream>
#include <stream_prefix.hpp>
class A {
public:
std::string id;
int count;
};
std::ostream &operator<<(std::ostream &os, const A &a)
{
os << get_prefix(os) << "Id: " << a.id << "\n";
os << get_prefix(os) << "Count: " << a.count << "\n";
return os;
}
int main() {
A a;
a.id = "foo";
a.count = 1;
std::cout << a << std::endl;
std::cout << set_prefix("==> ") << a << std::endl;
}
Full working demo here.
Note this set_prefix manipulator is "sticky", meaning the setting will remain on the stream after use, like most of the standard manipulators except for std::setw. If you want it to reset after you're done outputting an A object description, just add os << set_prefix(std::string{}); to the operator<< function.
This works, but it is very, very ugly and terrible code.
Couple of issues:
- operator<< has to be defined outside of the class, because you want to take in class A as the rhs argument, instead of invoking it like A::operator<<() - and actually taking in a second A class as an argument.
- cout cannot deal with a void output, so because you insist on chaining setting the prefix with the cout commant, it has to return an empty string object.
- If you don't want the prefix to be remembered, just do prefix.clear() at the end of the operator<< definition.
class A
{
public:
std::string id;
std::string prefix;
int count;
std::string set_prefix(const std::string& inp)
{
prefix = inp;
return std::string();
}
std::string get_prefix() const
{
return prefix;
}
};
std::ostream &operator<<(std::ostream &os, const A &input)
{
os << input.get_prefix() << "Id: " << input.id << "\n";
os << input.get_prefix() << "Count: " << input.count << "\n";
return os;
}
int main()
{
A class1;
class1.id = "test";
class1.count = 5;
std::cout << class1.set_prefix(" -") << class1; // endl removed, as your operator<< definition already has a "\n" at the end.
std::cout << class1.set_prefix("==>") << class1;
}

Calling an object from a class with Default Constructor

I'm wondering what a call to an object is supposed to display. I have a class called big_number that has a few different constructors. In another method, I'm declaring an object 'a' using class big_number as follows:
big_number a;
cout << "Default constructor gives " << a << endl;
And my constructor is:
big_number::big_number()
{
head_ptr = 0;
tail_ptr = 0;
positive = false;
digits = 0;
base = 10;
}
(Although I'm sure that this constructor is wrong).
The full code of the testing file:
int main()
{
int n1, n2;
unsigned int base;
string s;
char choice;
do
{
cout << "Type 'd' to test default constructor" << endl;
cout << "Type 'i' to test int constructor" << endl;
cout << "Type 's' to test string constructor" << endl;
cout << "Type 'a' to test assignment" << endl;
cout << "Type '>' to test input operator" << endl;
cout << "Type '=' to test comparison operators" << endl;
cout << "Type 'q' to quit" << endl;
cin >> choice;
if (toupper(choice) == 'D')
{
big_number a;
cout << "Default constructor gives " << a << endl;
}
//More Code
If by "call to an object" you mean your call of the operator<< on the object a with cout as the stream argument: It displays whatever you define it to display (in a member function of big_number or a free function). There is no "default" operator<< for user-defined classes. So, if you define it like
#include <iostream>
struct big_number
{
template<typename T>
friend T& operator<< (T& stream, const big_number& bn);
};
template<typename T>
T& operator<<(T& stream, const big_number& bn) {
return (stream << "Hello World");
}
int main()
{
big_number a;
std::cout << a << std::endl;
}
... it will just display "Hello world".
The purpose of making it a friend function is so it can access the private data members of big_number (since you usually want it to display something that depends on the data stored in the object, and not a constant "Hello world"). So, within the operator<< definition, you would probably iterate through the digits in your linked list and push them to the stream (if I understand correctly what you are trying to do).

Why doesn't implicit conversion work with wide ostream?

I have some behaviour that I do not understand. I observed this on VS2005, but IDEONE (using GCC 4.7.2) outputs basically the same.
Here's the code:
#include <iostream>
#include <string>
struct UserString {
const char* p;
operator const char*() const {
std::cout << "! " << __FUNCTION__ << std::endl;
return p;
}
UserString()
: p ("UserString")
{ }
};
struct WUserString {
const wchar_t* p;
operator const wchar_t*() const {
std::cout << "! " << __FUNCTION__ << std::endl;
return p;
}
WUserString()
: p (L"WUserString")
{ }
};
int main() {
using namespace std;
cout << "String Literal" << endl;
cout << string("std::string") << endl;
cout << UserString() << endl;
cout << static_cast<const char*>(UserString()) << endl;
wcout << L"WString Literal" << endl;
wcout << wstring(L"std::wstring") << endl;
wcout << WUserString() << endl;
wcout << static_cast<const wchar_t*>(WUserString()) << endl;
return 0;
}
Here's the output:
String Literal
std::string
! operator const char* **** "works"
UserString ****
! operator const char*
UserString
WString Literal
std::wstring
! operator const wchar_t* **** "doesn't" - op<<(void*) is used
0x80491b0 ****
! operator const wchar_t*
WUserString
What's going on here?!?
There is a partial specialization for basic_ostream
template<class _TraitsT>
basic_ostream<char, _TraitsT>&
operator<<(basic_ostream<char, _TraitsT>& _Stream, const char* _String);
which is a good fit for the cout << UserString() case.
There is nothing similar for wchar_t and WUserString(), so the member function
basic_ostream& operator<<(const void* _Address);
will be the best match for that (as in most "unusual" cases).

Which << is my overloaded operator in this statement?

I have an overloaded << operator from my reckful class implemented as follows:
ostream& operator << (ostream& os, const reckful& p)
{
os << p.PrintStuff();
return os;
}
PrintStuff() just being a member function of reckful that returns a string.
The way I understand things, if I were to write something like cout << reckobject << endl; in main(), cout << reckobject would take precedence and my overloaded << (using cout as the left operand and reckobject as the right operand) would return the ostream object os, leaving the expression os << endl; to be evaluated which would output the string and then end the line. So, the first << is the one I declared and the second is the standard << right?
However, my main question is... what is the sequence of events, which are the left and right operands, and which << operators are which when I run a statement like this:
cout << "reckful object = " << reckobject << "!" << endl;
Why does this work if there isn't an ostream object and a reckful object on either side of one << ?
Thanks.
If you notice standard way to implement << it returns the ostream itself. This is the critical piece
So something like
cout << "reckful object = " << reckobject << "!" << endl;
will be called once for
cout << "reckful object = "
This function call will return a ostream with which the second call will be made
namely
cout << reckobject;
so on an so forth.
You can test is out by implementing your << as
void operator << (ostream& os, const reckful& p)
{
os << 1;
}
in which case you can do
std::cout << p;
but not
std::cout << p << std::endl;
The operators make it harder to understand but consider this Point class
struct Point
{
Point& setX( int x) { X = x; return *this;}
Point& setY( int y) { Y = y; return *this;}
int X;
int Y;
};
The way setX and setY are defined, allows
Point p;
p.setX( 2 ).setY( 4 );
This is the same mechanism << is using to chain function calls.
Because each << returns a reference to cout. Because the operator << is left-associative, the calls are done from left to right, so
a << b << c
is equivalent to
(a << b) << c
which is equivalent1 to
operator<<(operator<<(a, b), c);
So in your example, you are doing
operator<<(operator<<(operator<<(operator<<(cout, "reckful object = "), reckobject), "!"), endl);
As you can see, each << depends on the return value of the previous << (or just cout in case there is no further left <<). If you change one of the return types of the <<s to void, you effectively stop any more << calls, because void can't be used as an argument to a function.
1 It's not exactly equivalent because in that example, all operator<< are free functions, whereas in reality, some can be member functions, so you could have a mix of member and non-member calls like
operator<<(a, b).operator<<(c);
or
operator<<(a.operator<<(b), c);