C++: Overloading << operator with function pointers - c++

I have a class "stampstream" that is essentially intended to work like 'cout'. The two functions that follow are outside the class. This is the part that works.
class stampstream: public std::ostream
{
//code
stampstream& operator<<(stampstream& (*x)(void))
{
//code
}
//code
};
stampstream& endr()
{
//nocode
}
stampstream& (*endrow)(void)=endr;
In main:
stampstream s;
s << "teststring1" << endrow;
Note that "endrow" is essentially 'endl'. This part works perfectly fine, compiles and executes with the right output.
Now, I'm trying to overload << with another possible row(int) function. This is the part that doesn't work. Again, it's part of the same class as above and the following 2 functions are outside the class.
class stampstream: public std::ostream
{
//code
stampstream& operator<<(stampstream& (*r)(int y))
{
//code
}
//code
};
stampstream& ro(int y)
{
//nocode
}
stampstream& (*row)(int)=ro;
In main:
s << "teststring2" << row(5);
This is the error I get:
error: invalid user-defined conversion from ‘stampstream’ to ‘stampstream& (*)(int)’ [-fpermissive]
What am I doing wrong with row ?

The problem is that in
s << "teststring2" << row(5);
function call has higher precedence than <<, so this calls the function row points at and then tries to pass its return value (a stampstream &) to operator<<.
What you want is
s << "teststring2" << row;
This doesn't call the function and instead passes the pointer to operator<<. Inside that function, when you want to call x, you'll need to provide the argument.
It sounds like what you are trying to do is to have a function row that creates a functor object that you can then pass to operator<<. You can do that in C++11 with a lambda:
class stampstream: public std::ostream
{
//code
stampstream& operator<<(std::function<stampstream&(void)> r)
{
//code
}
//code
};
std::function<stampstream&(void)> row(int x)
{
return [x]()->stampstream & {
//code
}
}
Which you can call as:
s << "teststring2" << row(5);
The call to row happens first, which constructs a lambda and returns it (but doesn't yet run the code in it). The functor is passed to operator<< and when that function calls r, it will call the code in the lambda (which can refer to the x param, which was bound by value, so copied into the lambda.)

Since Chris has already answered your question, I wanted to advise you of alternatives to your current method:
Your stampstream class should use a specialized std::streambuf that writes out the stamp inside overflow(). There's no need to extend an std::ostream and reimplement the input operators. For an example of how to do this, see this thread.
You seem to be using endrow and row like manipulators. Operator overloads already exist for manipulators that do not take arguments at the call site. You can have endrow take and return an object of type std::ostream&. For row you can have it return a class that overloads the inserter to allow the syntax you want:
struct row_impl
{
row_impl(int row) : row(row) { }
// Write out the row and return the stream
friend std::ostream& operator<<(std::ostream& os, row_impl const& rimpl);
private:
int row;
};
std::ostream& operator<<(std::ostream& os, row_impl const& rimpl)
{
// This is where the code for your original row() function goes
}
// write out to and return the stampstream instance
std::ostream& endrow(std::ostream& os);
row_impl row(int row)
{
return row_impl(row);
}
Now s << endrow and s << row(5) will work without having to add anything to your stampstream class.

Related

How to overload 2 versions of operator<< in a C++ class

I am overloading operator<< as follows :
std::ostream& operator<<(std::ostream& o, const MyClass& myobj);
Now, I would like to have 2 versions of operator<<, one that would display a short description of my object, and another that would display a longer version.
For example, MyClass could contain information about a client. In the short version I would display just the name, and in the long version I would display more details like birthday, address, etc.
Is there a way to do that in C++ ?
I know I could have a method of MyClass that receives the stream, but it would be called like this :
myObj.DisplayShort(cout)
or
myObj.DisplayLong(cout)
but I would like to stay with a syntax similar to the usual form :
cout << myObj << endl;
The standard way is to create a custom formatting flag and a custom manipulator using std::ios_base::xalloc and std::ios_base::iword.
So you have
class MyClass {
static int fmt_flag_index;
enum fmt_flag { output_short, output_long };
}
You initialize fmt_flag_index somewhere at the program startup:
int MyClass::fmt_flag_index = std::ios_base::xalloc();
Here's your custom formatting flag ready to use. Now IO manipulators can set it:
std::ios_base& myclass_short(std::ios_base& os)
{
os.iword(MyClass::fmt_flag_index) = static_cast<int>(MyClass::output_short);
return os;
}
std::ios_base& myclass_long(std::ios_base& os)
{
os.iword(MyClass::fmt_flag_index) = static_cast<int>(MyClass::output_long);
return os;
}
And operator<< access it:
std::ostream& operator<<(std::ostream& os, MyClass& f)
{
switch (static_cast<MyClass::fmt_flag>(os.iword(MyClass::fmt_flag_index)))
{
case MyClass::output_short: ...;
case MyClass::output_long: ...;
}
}
Use it like this:
MyClass myobj;
std::cout << myclass_long << myobj;
std::cout << myclass_short << myobj;
Demo
I would use a printing adaptor:
class Adaptor
{
MyClass &adaptee;
operator <<
}
And then you can implement different logic based on:
Multiple adapter classes
Single adapter class with a data member
Single adapter class with a template argument

C++ How do I implement this one parameter constructor?

In this project, I have to create a class called Chain. A chain will be a list of values (like an array). The thing is I have to create this chain without the use of the STL library.
Right now, I have to implement this one parameter constructor:
Chain(const Object& item)
{
// Write something.
}
"Object" by the way is just the name of the template for the class.
I have these two private variables as part of the class:
size_t size_;
Object *array_;
Let's say I wanted to make this call from main:
Chain<int> d{7};
That's just saying pass 7 to the one parameter constructor.
How would I go about implementing this one parameter constructor?
Also, I need to be able to print out this class if from main I type for example:
Chain<int> d{7}; // A chain containing 7 should be created.
cout << d; // Should just print [7]
In order to do that, I have to implement this overloaded << operator:
// Overloading the << operator.
friend std::ostream &operator<<(std::ostream &out, const Chain &a_chain)
{
// Print the chain.
return out;
}
Attempted code so far:
// One parameter constructor.
Chain(const Object& item)
{
array_ = new Object[item];
// array_=item;
size_++;
}
// Overloading the << operator.
friend std::ostream &operator<<(std::ostream &out, const Chain &a_chain)
{
cout << array_ << endl;
return out;
}
With these types of things, it's best to take things one step at a time, making sure you've got each small piece working before adding additional complexity. See How to debug small programs for more details.
For the code (now) you've shown, here is code that does exactly what you've described, and nothing more.
template<typename T>
struct Chain
{
T value;
};
// Overloading the << operator.
template<typename T>
std::ostream &operator<<(std::ostream &out, const Chain<T> &a_chain)
{
out << a_chain.value << std::endl;
return out;
}
int main()
{
Chain<int> d{ 7 }; // A chain containing 7 should be created.
std::cout << d; // Should just print [7]
return 0;
}
Note that using Object* array_ isn't necessary to get this snippet of code working. Once you're satisfied with what this does, you can add more pieces. For example, if you really are trying to implement your own std::vector<>-like class (bad idea), your next step might be to remove templates as that's an additional complexity.

How to use osstream properly in c++. Is there a easy or better way of implementing logging of program execution flow to a file in c++

While trying to work with the << operator and std::basic_ostream, I ran into an error and I don't understand why it's a problem.
In the code samples below, the 1st statement works for both version but the 2nd statement only works with version 1
*TestLog::getInstance() << "Hi this is ";
*TestLog::getInstance() << "Hi this is " << endl;
What exactly happens if we overload the operator << std::basic_ostream?.
Version 1
ofstream logFile("log.txt")
class TestLog : public std::basic_ostream<char, std::char_traits<char> >
{
public:
static TestLog* getInstance()
typedef std::basic_ostream<char,std::char_traits<char> > SuperType;
TestLog& operator<<(SuperType& (*manip)(SuperType& ))
{
stream1_ << manip;
return *this;
}
template<typename T>
TestLog& operator<<(const T& t)
{
stream1_ << t;
return *this;
}
protected:
TestLog();
private:
static TestLog* _instance;
std::ostream& stream1_;
};
TestLog* TestLog::getInstance()
{
if(_instance == 0)
{
_instance = new TestLog();
}
return _instance;
}
TestLog::TestLog():SuperType(logFile.rdbuf()), stream1_(logFile)
{
}
Version 2
class TestLog
{
public:
static TestLog* getInstance()
template<typename T>
TestLog& operator<<(const T& t)
{
stream1_ << t;
return *this;
}
protected:
TestLog();
private:
static TestLog* _instance;
std::ostream& stream1_;
};
TestLog* TestLog::getInstance()
{
if(_instance == 0)
{
_instance = new TestLog();
}
return _instance;
}
TestLog::TestLog():stream1_(logFile)
{
}
The statements as posted all "work" with both approaches shown. I guess you meant to use a manipulator like std::flush (maybe even std::endl which shouldn't be used anyway) instead of "a test" for the second statement as that would, indeed, only work with the first apporoach: std::flush is a function template whose type needs to be deduced upon use. Since your [misguided] implementation of the output operator itself is a template the template arguments for std::flush cannot be deduced and the compilation fails. In the first approach your class contains an explicit overload dealing with the type of a template instantiation of the manipulators which is sufficient to deduce the necessary template argument.
Either way, your approach to creating a new stream is not a good idea at all! Both of your approaches fail, e.g., when trying to pass the resulting "stream" to something which expects and std::ostream& as argument. For output streams there are two independent dimensions which can vary (similarly for input streams):
For any new type objects can be formatted in a specific way. This is done by overloading the shift operator for std::ostream& and the object's type.
The destination of characters can be modified. This is done by inheriting from std::streambuf and overriding the appropriate virtual function, notably overflow().
Your code tries to change the destination of characters by overloading the shift operator. Doing so is not intended to work and does create subtle problems like the problem not working with manipulators, functions taking std::ostream& as argument, or attempts to change the format flags of the "stream" using the various accessor functions.

Why is my overloaded << operator not working?

I'm trying to understand how to properly overload the "<<" operator so that I can use
std::cout << my_object;
to print useful debug messages. In particular, I need to have an implementation of << for each of my subclasses, so I'm declaring << to be virtual in the superclass.
Right now I'm stuck with the following piece of code
#include <iostream>
using namespace std;
class Shape {
public:
virtual ~Shape() { };
virtual ostream& operator<<(std::ostream &strm) = 0;
};
class Square : public Shape {
int size;
public:
Square() { size = 10; }
~Square() { }
ostream& operator<<(std::ostream &strm) {
return strm << "a square with size " << size;
}
};
int main() {
Square *my_square = new Square();
cout << "my_square is " << my_square << "\n";
}
which (I think) should be working, but doesn't. What I get when using "<<" is that the pointer value of my_square gets printed, rather than the result of the overloaded << .
$ ./a.out
my_square is 0xcacc20
What am I missing here?
operator<< can't be a member function. This is because of the order of the arguments. The stream has to come first.
When calling an overloaded operator, such as:
os << object;
the compiler will attempt to look up both
os.operator<<(object);
and
operator<<(os, object);
(The rules for this can be rather complex, I won't attempt to describe them here.)
Because the stream always comes on the left, your member function will never be found, since it would have to be called as:
object.operator<<(os);
You need to write a free function like:
ostream& operator<<(std::ostream &strm, Square const& square) {
return strm << "a square with size " << square.size();
}
(where Square::size() returns the size member).
Then you need to remember to dereference your pointer too:
std::cout << *my_square << '\n';
Although I see no reason to be dynamically allocating my_square in this example anyway. Just stick it on the stack as a local variable.
If the aim here is ultimately to be able to print any Shape&, and have the printed output follow the "real" type, you would need to create:
virtual std::ostream& print(std::ostream&) const = 0;
in the Shape base class, and override it in each derived class, then have a free function:
std::ostream& operator<<(std::ostream& os, Shape const& shape)
{
return shape.print(os);
}
It is often advised to make all binary operators on your type non-member functions, so that both arguments are treated equally, and the operation remains commutative. See Scott Meyers, Effective C++ (3rd Edition), Item 24, (or find a summary online).
As noted by others, the problem is that operator << can't be member function (because of the order of arguments). The canonical way to do this is to have operator <<(const Shape&) call a virtual function in Shape
class Shape {
friend ostream& operator<<(std::ostream& str, const Shape& shape);
virtual void do_print(ostream& str) = 0;
public:
virtual ~Shape() { };
};
ostream& operator<<(std::ostream& str, const Shape& shape) {
shape.do_print(str);
return str;
}
Note that it is legal to have do_print be private, even though it is going to be (must be) overridden by derived classes. You could make it protected though if you like.
What am I missing here?
You have created operator which will get you class as a first argument and stream as the second.
my_square << std::cout;
I'd create free function and to make it dynamic I'd call some virtual method in it

How to define a static operator<<?

Is it possible to define a static insertion operator which operates on the static members of a class only? Something like:
class MyClass
{
public:
static std::string msg;
static MyClass& operator<< (const std::string& token) {
msg.append(token);
return *this; // error, static
}
};
alternatively:
static MyClass& operator<< (MyClass&, const std::string &token)
{
MyClass::msg.append(token);
return ?;
}
This is how I would like to use it:
MyClass << "message1" << "message2";
Thank you!
What I would probably do in your situation, is create another class that overloads the operator<<, then make a static member of that type. Like this:
class MyClass
{
public:
static std::string msg;
struct Out {
Out & operator<< (const std::string& token) {
MyClass::msg.append(token);
return *this;
}
};
static Out out;
};
Using it is not quite what you asked for, but close enough I think:
MyClass::out << "message1" << "message2";
If all the members of MyClass are static, it's possible to return a fresh instance.
However, returning a reference poses a problem. There are two solutions:
define a static instance
pass by copy, and not by reference.
The second approach is easiest:
static MyClass operator<< (MyClass, const std::string &token)
{
MyClass::msg.append(token);
return MyClass();
}
The first is one line more:
static MyClass& operator<< (MyClass&, const std::string &token)
{
static MyClass instance;
MyClass::msg.append(token);
return instance;
}
Usage is very close to what you want:
MyClass() << "message1" << "message2";
However, I would not recommend to do this. Why don't you just just use a std::ostringstream? You'll get formatting and some more for free. If you really need global access, declare a global variable.
If you want to use your class as cout, what you can do is example
#include <iostream>
using namespace std;
namespace trace
{
class trace
{
public:
trace& operator<< (const std::string& echo)
{
std::cout << echo << std::endl;
return *this;
}
};
trace t; // Note that we created variable so we could use it.
};
using namespace trace; // Note that we use same namespace so we dont need to do trace::t
int main(int argv, char** argc)
{
t << "Server started..."
<< "To exit press CTRL + Z";
return 0;
}
Output should look like each string in new line like this:
Server started...
To exit press CTRL + Z
You can't. A class-name / type is not a value in itself, you would need an expression like
class Foobar {...};
std::cout << Foobar << std::endl;
so that your static operator<< would be usable, but that is not valid C++. The grammar summary at A.4 shows that putting a type's name there is not valid.
Consider also that operator overloads are just functions with flaky names:
T operator<< (T, T)
^^^^^^^^^^ flaky name, basically same as:
T left_shift (T, T)
And functions in C++ (and most other languages, e.g. C#) can only work on instances of types, not types themselves.
However, C++ offers templates which have type arguments, howhowever, that would not help you to overload functions upon types.