Using ofstream* wrapper class with overloaded << operator on endl - c++

C++
This is an attempt to make a class that mimics the output behavior of using the << operator of an ofstream, as far as being able to use std::endl and write strings is concerned. The class has a single data member, the ofstream pointer. The class has two overloaded << operators, one that takes an std::string and another that takes a pointer to a function, whose argument is an ostream reference and returns an ostream reference. That is the signature of std::endl, according to this. Technically, the below program works with the given input. It is able to print to file, two lines of text separated by two std::endls. However, I want my non-string parameter overloaded << operator to accept std::endl only, not something that merely matches its signature. I tried various combinations of placing std::endlin the argument list, with and without * and with and without &, but I got compiler errors for every combination. C++11 answers are also welcome.
#include <fstream>
#include <iostream>
#include <string>
class TextOut
{
public:
TextOut(std::ofstream* ofsPar) : ofs(ofsPar) {}
TextOut& operator<<(std::string s)
{
*ofs << s;
return *this;
}
TextOut& operator<<(std::ostream& (*endlPar) (std::ostream& os))
{
*ofs << std::endl;
return *this;
}
private:
std::ofstream* ofs;
};
int main()
{
std::cout << "Enter filename: ";
std::string filename;
std::cin >> filename;
std::ofstream myofstream(filename.c_str());
TextOut myTextOut(&myofstream);
myTextOut << "Hello," << std::endl << std::endl << "spacious world.";
return 0;
}
Output:
Hello,
spacious world.

If I look at my ostream header file I see this for endl:
template<typename _CharT, typename _Traits> inline basic_ostream<_CharT, _Traits>&
endl(basic_ostream<_CharT, _Traits>& __os)
{
return flush(__os.put(__os.widen('\n')));
}
so it looks like you would need to inherit from basic_ostream to make this work. Not sure you really want to do that.

As far as I know there is no way to enforce a parameter to be a specific value at compile time.
If compile-time enforcement is not a requirement, you could use a simple assert like this to enforce that the parameter is std::endl:
assert(static_cast<std::ostream& (*) (std::ostream& os)>(&std::endl) == endlPar);

Related

Printing private variables in Class via overloaded '<<'

I'm switching from C to C++ and i have some basic but annoying problem with Class hermetization. I did some research here, but I'm probably really dumb and I can't use yor methods properly, could you help me?
The problem is printing private member of a class via overloaded '<<' operator.
Let's get to the code:
In file Vector.hh
#include <iostream>
class Vector {
double Val1, Val2, Val3;
public:
void PrintVector(Vector);
//There is also a constructor but it doesn't really matter
}
In File Vector.cpp
#include "Vector.hh"
#include <iostream>
void Vector::PrintVector(Vector Wek)
{
std::cout << Wek.Val1 << Wek.Val2 << Wek.Val3 << std::endl;
}
std::istream& operator >> (std::istream &Strm, Vector &Wek)
{
//It actually works with no problem so i'll pass it
}
std::ostream& operator << (std::ostream &Strm, Vector Wek)
{
Vector::PrintVector(Wek);
return Strm;
}
and in main.cpp
#include Vector.hh
#include <iostream>
using namespace std;
int main()
{
Vector Vector1;
cout << endl << " Start " << endl << endl;
cin >> Vector1;
cout << Vector1;
}
When I try to compile g++ says:
g++ -c -g -Iinc -Wall -pedantic -o obj/Vector.o src/Vector.cpp
src/Vector.cpp:12:37: error: no 'void Vector::PrintVector(Vector)' member function declared in class 'Vector'
void Vector::PrintVector(Vector Wek)
^
src/Vector.cpp: In function 'std::ostream& operator<<(std::ostream&, Vector)':
src/Vector.cpp:29:1: error: 'PrintVector' is not a member of 'Vector'
Vector::PrintVector(Wek);
make: Fatal error: Command failed for target `obj/Vector.o'
Could you please give me a hand with it so I learn basics properly?
Either a class function is static and not called on any particular class object, or it is non-static and must be called on an instance of the class, which can be used inside the function. You have mixed the approach. You need to select one of the two:
class Vector
{
static void PrintVector(const Vector& Wek)
{
std::cout << Wek.Val1 << Wek.Val2 << Wek.Val3 << std::endl;
}
};
// to call
Vector::PrintVector(Wek);
or
class Vector
{
void PrintVector() const
{
std::cout << Wek.Val1 << Wek.Val2 << Wek.Val3 << std::endl;
}
};
// to call
Wek.PrintVector();
Either is fine, but I would prefer the latter.
The other problem is how you have implemented the stream operator. This operator takes a stream to output the object to. You have called this stream Strm, but it is never used in your operator. Your print function is hardcoded to the cout stream.
I suggest you remove the PrintVector function and implement your operator as follows:
class Vector
{
friend std::ostream& operator << (std::ostream &Strm, const Vector& Wek);
};
std::ostream& operator << (std::ostream &Strm, const Vector& Wek)
{
Strm << Wek.Val1 << Wek.Val2 << Wek.Val3 << "\n";
return Strm;
}
Now you can output to any type of stream, such as a file stream. You also needed to declare the operator as a friend to allow it to access the private members.
I changed some parameters to reference to increase speed and also replaced endl with "\n" which is faster when writing to files (you can google why).
You may want to consider adding spaces between the output members, as this makes it easer to read back.
Hope this helps.
Your error is simple. You cannot use an instance method without an object. Try:
Wek.PrintVector();
Also, pass it by constant reference, don't copy.
General way to do this is to make operator<<() a friend function of the class. Friend function can access private members of the class. So operator<<() can directly access private members for printing them. Refer sample.
Defining a public function PrintVector for printing is a bad idea. Since it is public, user (developer using your class) might start using it instead of << operator. You don't want user to use it.

c++ get stream modifier from << overload

I have overloaded the stream insertion operator like this :
template<class Ch, class Tr, class word_type>
std::basic_ostream<Ch, Tr>&
operator << (std::basic_ostream<Ch, Tr>& s, const Mabit::mabit<word_type>& obj)
{
s << obj.to_string(Mabit::DEC, ',');
return s;
}
(mabit being the class for which i wanted the overload to work)
That is, since i can give different argument to the to_string method, i would like to be able to use standard stream modifier like std::dec, std::hex ... in a way that i could retrieve them from the overloaded operator to prepare the good argument as parameter for to_string
If i could also get the locale being used (to extract the separator for thousands) , it would be helpfull for the second argument too...
Is that possible ?
You can use std::basic_ostream::flags() to identify whether an format specifier was used.
http://en.cppreference.com/w/cpp/io/ios_base/flags
From http://www.cplusplus.com/reference/locale/numpunct/thousands_sep/
#include <iostream>
#include <locale>
using namespace std;
int main ()
{
int q=10977;
char separator = use_facet<numpunct<char> >(cout.getloc()).thousands_sep ();
cout << q/1000 << separator << q%1000 << endl;
return 0;
}
I suppose you can just replace cout with your stream argument in this example

Problem with overriding "operator<<" in class derived from "ostream"

I want to make a class based on "ostream" that does some auto-formatting to generate comma- or tab-separated-value files. My idea was to override "operator<<" to have it insert a separator before each value (except at the beginning and end of a line), and also to quote strings before writing them. Within the overriding "operator<<" method, I wanted to call the method of the base class, but I can't get it to work right.
Here's an example (compiles with g++ 4.3.3):
#include <iostream>
#include <ostream>
#include <string>
using namespace std;
class MyStream: public ostream
{
public:
MyStream(ostream& out): ostream(out.rdbuf()) {}
template <typename T> MyStream& operator<<(T value)
{
ostream::operator<<('+');
ostream::operator<<(value);
ostream::operator<<('+');
return *this;
}
};
template<> MyStream& MyStream::operator<< <string>(string value)
{
ostream::operator<<('*');
ostream::write(value.c_str(), value.size()); // ostream::operator<<(value);
ostream::operator<<('*');
return *this;
}
int main()
{
MyStream mystr(cout);
mystr << 10;
cout << endl;
mystr << "foo";
cout << endl;
mystr << string("test");
cout << endl;
return 0;
}
The two "operator<<" methods (template and specialization) are there to handle strings differently than everything else. But:
The characters ('+'/'*') are printed as numbers and not characters.
The C-String "foo" prints as a memory address (I think).
If the "write" line is exchanged with the commented part, the compiler complains that there's "no matching function for call to 'MyStream::operator<<(std::string&)'", even though I thought I was explicitly calling the base class method.
What am I doing wrong? Any help greatly appreciated.
The operator<< overloads that prints strings and characters are free functions. But as you force calling member functions, you will force them to convert to one candidate of the member functions declared in ostream. For '*', it will probably use the int overload, and for "foo", it will probably use the const void* overload.
I would not inherit ostream, but instead store the ostream as a reference member, and then delegate from your operator<< to it. I would also not make operator<< a member, but rather a free function template, and not specialize but overload the operator<< for both std::string and char const*.
Something like the following might work:
include
#include <ostream>
#include <string>
using namespace std;
class MyStream: public ostream
{
public:
MyStream(ostream& out): ostream(out.rdbuf()) {}
template <typename T> MyStream& operator<<(const T& value)
{
(ostream&)*this << '+' << value << '+';
return *this;
}
MyStream& operator<< (const string& value)
{
(ostream&)*this << '*' << value << '*';
return *this;
}
MyStream& operator<< (const char* cstr)
{
(ostream&)*this << '(' << cstr << ')';
return *this;
}
};

std::endl is of unknown type when overloading operator<<

I overloaded operator <<
template <Typename T>
UIStream& operator<<(const T);
UIStream my_stream;
my_stream << 10 << " heads";
Works but:
my_stream << endl;
Gives compilation error:
error C2678: binary '<<' : no operator found which takes a left-hand operand of type 'UIStream' (or there is no acceptable conversion)
What is the work around for making my_stream << endl work?
std::endl is a function and std::cout utilizes it by implementing operator<< to take a function pointer with the same signature as std::endl.
In there, it calls the function, and forwards the return value.
Here is a code example:
#include <iostream>
struct MyStream
{
template <typename T>
MyStream& operator<<(const T& x)
{
std::cout << x;
return *this;
}
// function that takes a custom stream, and returns it
typedef MyStream& (*MyStreamManipulator)(MyStream&);
// take in a function with the custom signature
MyStream& operator<<(MyStreamManipulator manip)
{
// call the function, and return it's value
return manip(*this);
}
// define the custom endl for this stream.
// note how it matches the `MyStreamManipulator`
// function signature
static MyStream& endl(MyStream& stream)
{
// print a new line
std::cout << std::endl;
// do other stuff with the stream
// std::cout, for example, will flush the stream
stream << "Called MyStream::endl!" << std::endl;
return stream;
}
// this is the type of std::cout
typedef std::basic_ostream<char, std::char_traits<char> > CoutType;
// this is the function signature of std::endl
typedef CoutType& (*StandardEndLine)(CoutType&);
// define an operator<< to take in std::endl
MyStream& operator<<(StandardEndLine manip)
{
// call the function, but we cannot return it's value
manip(std::cout);
return *this;
}
};
int main(void)
{
MyStream stream;
stream << 10 << " faces.";
stream << MyStream::endl;
stream << std::endl;
return 0;
}
Hopefully this gives you a better idea of how these things work.
The problem is that std::endl is a function template, as your operator <<
is. So when you write:
my_stream << endl;
you'll like the compiler to deduce the template parameters for the operator
as well as for endl. This isn't possible.
So you have to write additional, non template, overloads of operator << to
work with manipulators. Their prototype will look like:
UIStream& operator<<(UIStream& os, std::ostream& (*pf)(std::ostream&));
(there are two others, replacing std::ostream by std::basic_ios<char> and
std::ios_base, which you have also to provide if you want to allow all
manipulators) and their implementation will be very similar to the one of
your templates. In fact, so similar that you can use your template for
implementation like this:
typedef std::ostream& (*ostream_manipulator)(std::ostream&);
UIStream& operator<<(UIStream& os, ostream_manipulator pf)
{
return operator<< <ostream_manipulator> (os, pf);
}
A final note, often writing a custom streambuf is often a better way to
achieve what one try to achieve applying to technique you are using.
I did this to solve my problem, here is part of my code:
template<typename T>
CFileLogger &operator <<(const T value)
{
(*this).logFile << value;
return *this;
}
CFileLogger &operator <<(std::ostream& (*os)(std::ostream&))
{
(*this).logFile << os;
return *this;
}
Main.cpp
int main(){
CFileLogger log();
log << "[WARNINGS] " << 10 << std::endl;
log << "[ERRORS] " << 2 << std::endl;
...
}
I got the reference in here http://www.cplusplus.com/forum/general/49590/
Hope this can help someone.
See here for better ways of extending IOStreams. (A bit outdated, and tailored for VC 6, so you will have to take it with a grain of salt)
The point is that to make functors work (and endl, which both outputs "\n" and flushes is a functor) you need to implement the full ostream interface.
The std streams are not designed to be subclassed as they have no virtual methods so I don't think you'll get too far with that. You can try aggregating a std::ostream to do the work though.
To make endl work you need to implement a version of operator<< that takes a pointer-to-function as that is how the manipulators such as endl are handled i.e.
UStream& operator<<( UStream&, UStream& (*f)( UStream& ) );
or
UStream& UStream::operator<<( UStream& (*f)( UStream& ) );
Now std::endl is a function that takes and returns a reference to a std::basic_ostream so that won't work directly with your stream so you'll need to make your own version which calls through to the std::endl version in your aggregated std::iostream.
Edit: Looks likes GMan's answer is better. He gets std::endl working too!
In addition to the accepted answer, with C++11 it is possible to overload operator<< for the type:
decltype(std::endl<char, std::char_traits<char>>)

Custom manipulator for C++ iostream

I'd like to implement a custom manipulator for ostream to do some manipulation on the next item being inserted into the stream. For example, let's say I have a custom manipulator quote:
std::ostringstream os;
std::string name("Joe");
os << "SELECT * FROM customers WHERE name = " << quote << name;
The manipulator quote will quote name to produce:
SELECT * FROM customers WHERE name = 'Joe'
How do I go about accomplishing that?
Thanks.
It's particularly difficult to add a manipulator to a C++ stream, as one has no control of how the manipulator is used. One can imbue a new locale into a stream, which has a facet installed that controls how numbers are printed - but not how strings are output. And then the problem would still be how to store the quoting state safely into the stream.
Strings are output using an operator defined in the std namespace. If you want to change the way those are printed, yet keeping the look of manipulators, you can create a proxy class:
namespace quoting {
struct quoting_proxy {
explicit quoting_proxy(std::ostream & os):os(os){}
template<typename Rhs>
friend std::ostream & operator<<(quoting_proxy const& q,
Rhs const& rhs) {
return q.os << rhs;
}
friend std::ostream & operator<<(quoting_proxy const& q,
std::string const& rhs) {
return q.os << "'" << rhs << "'";
}
friend std::ostream & operator<<(quoting_proxy const& q,
char const* rhs) {
return q.os << "'" << rhs << "'";
}
private:
std::ostream & os;
};
struct quoting_creator { } quote;
quoting_proxy operator<<(std::ostream & os, quoting_creator) {
return quoting_proxy(os);
}
}
int main() {
std::cout << quoting::quote << "hello" << std::endl;
}
Which would be suitable to be used for ostream. If you want to generalize, you can make it a template too and also accept basic_stream instead of plain string. It has different behaviors to standard manipulators in some cases. Because it works by returning the proxy object, it will not work for cases like
std::cout << quoting::quote;
std::cout << "hello";
Try this:
#include <iostream>
#include <iomanip>
// The Object that we put on the stream.
// Pass in the character we want to 'quote' the next object with.
class Quote
{
public:
Quote(char x)
:m_q(x)
{}
private:
// Classes that actual does the work.
class Quoter
{
public:
Quoter(Quote const& quote,std::ostream& output)
:m_q(quote.m_q)
,m_s(output)
{}
// The << operator for all types. Outputs the next object
// to the stored stream then returns the stream.
template<typename T>
std::ostream& operator<<(T const& quoted)
{
return m_s << m_q << quoted << m_q;
}
private:
char m_q;
std::ostream& m_s;
};
friend Quote::Quoter operator<<(std::ostream& str,Quote const& quote);
private:
char m_q;
};
// When you pass an object of type Quote to an ostream it returns
// an object of Quote::Quoter that has overloaded the << operator for
// all types. This will quote the next object and the return the stream
// to continue processing as normal.
Quote::Quoter operator<<(std::ostream& str,Quote const& quote)
{
return Quote::Quoter(quote,str);
}
int main()
{
std::cout << Quote('"') << "plop" << std::endl;
}
[EDIT: "True manipulator semantics" (i.e. a persistent quoting state) could also be achieved by wrapping an std::ostream rather than deriving from it, as noted by BenĂ´it in the comments.]
To the best of my knowledge this cannot be done directly without either deriving a new class from std::ostream or similar, or wrapping such a class in another class that forwards most methods to its contained std::ostream object. That's because, for the code example you provide to work, you will need to somehow modify the behaviour of std::ostream& operator<<(std::ostream&, std::string const&), which is defined somewhere in the iostreams hierarchy (or possibly wherever std::string is defined). You will also need to use the (somewhat ugly) facilities in ios_base to record a boolean flag holding the current quoting state. Look up ios_base::xalloc(), ios_base::iword() and ios_base::pword() to find out how to do that.
However, if you are willing to use the following syntax:
os << "SELECT * FROM customers WHERE name = " << quote(name);
This can be done very simply using a global function (in an appropriate namespace of course).
This syntax has the advantage that quoting is not persistent, meaning it can't "leak out" when a function sets the quote formatting flag and forgets to set it back to its original value.
Or just use OTL which basically already implements a stream interface for SQL very similarly to your example.