I've written a custom stream class that outputs indented text and that has manipulators that can change the indent level. All of the indenting work is implemented in a custom stream buffer class, which is used by the stream class. The buffer is working (i.e. text is indented in the output), but I can't get my manipulators to work. I was reading in a lot of places how ostream (which my class extends) overloads the operator<< like this:
ostream& ostream::operator << ( ostream& (*op)(ostream&))
{
// call the function passed as parameter with this stream as the argument
return (*op)(*this);
}
Which means it can take in a function as a parameter. So why aren't my "indent" or "deindent" stream functions being recognized? I'm sure I have to do some overloading of operator<<, but shouldn't I not need to? See below for my code:
#include <iostream>
#include <streambuf>
#include <locale>
#include <cstdio>
using namespace std;
class indentbuf: public streambuf {
public:
indentbuf(streambuf* sbuf): m_sbuf(sbuf), m_indent(4), m_need(true) {}
int indent() const { return m_indent; }
void indent() { m_indent+=4; }
void deindent() { if(m_indent >= 4) m_indent-= 4; }
protected:
virtual int_type overflow(int_type c) {
if (traits_type::eq_int_type(c, traits_type::eof()))
return m_sbuf->sputc(c);
if (m_need)
{
fill_n(ostreambuf_iterator<char>(m_sbuf), m_indent, ' ');
m_need = false;
}
if (traits_type::eq_int_type(m_sbuf->sputc(c), traits_type::eof()))
return traits_type::eof();
if (traits_type::eq_int_type(c, traits_type::to_char_type('\n')))
m_need = true;
return traits_type::not_eof(c);
}
streambuf* m_sbuf;
int m_indent;
bool m_need;
};
class IndentStream : public ostream {
public:
IndentStream(ostream &os) : ib(os.rdbuf()), ostream(&ib){};
ostream& indent(ostream& stream) {
ib.indent();
return stream;
}
ostream& deindent(ostream& stream) {
ib.deindent();
return stream;
}
private:
indentbuf ib;
};
int main()
{
IndentStream is(cout);
is << "31 hexadecimal: " << hex << 31 << endl;
is << "31 hexadecimal: " << hex << 31 << endl;
is << "31 hexadecimal: " << hex << 31 << deindent << endl;
return 0;
}
Thanks!
Your manipulator should be declared as a function which accepts just one argument of type ostream&. However, if you make it a member function, you know there is an implicit this argument being passed to the function as well.
Thus, you should rather declare your manipulator as a free, non-member function, making it friend of your class so that it can access its private member ib:
class IndentStream : public ostream {
public:
IndentStream(ostream &os) : ib(os.rdbuf()), ostream(&ib){};
ostream& indent(ostream& stream) {
ib.indent();
return stream;
}
friend ostream& deindent(ostream& stream);
// ^^^^^^
private:
indentbuf ib;
};
ostream& deindent(ostream& stream)
{
IndentStream* pIndentStream = dynamic_cast<IndentStream*>(&stream);
if (pIndentStream != nullptr)
{
pIndentStream->ib.deindent();
}
return stream;
}
int main()
{
IndentStream is(cout);
is << "31 hexadecimal: " << hex << 31 << endl;
is << "31 hexadecimal: " << hex << 31 << deindent << endl;
is << "31 hexadecimal: " << hex << 31 << endl;
return 0;
}
Alternatively, if you really want your function to be a member, you could make it static:
class IndentStream : public ostream {
public:
IndentStream(ostream &os) : ib(os.rdbuf()), ostream(&ib){};
ostream& indent(ostream& stream) {
ib.indent();
return stream;
}
static ostream& deindent(ostream& stream)
{
IndentStream* pIndentStream = dynamic_cast<IndentStream*>(&stream);
if (pIndentStream != nullptr)
{
pIndentStream->ib.deindent();
}
return stream;
}
private:
indentbuf ib;
};
However, this would force you to use a qualified name to refer to it:
int main()
{
IndentStream is(cout);
is << "31 hexadecimal: " << hex << 31 << endl;
is << "31 hexadecimal: " << hex << 31 << IndentStream::deindent << endl;
// ^^^^^^^^^^^^^^
is << "31 hexadecimal: " << hex << 31 << endl;
return 0;
}
Related
I'm sorry the title may be inaccurate.I'm new to C++.
Here is my code and output...
#include <iostream>
#include <sstream>
using namespace std;
class LogLine {
private:
stringstream ss;
string message;
public:
~LogLine() {
ss << "\n";
message = ss.str();
cout << message;
message = "";
}
template <class T>
LogLine& operator<<(const T& thing) {
ss<< thing;
return *this;
}
LogLine& operator<<(std::ostream &(*manip)(std::ostream &)) {
manip(ss);
return *this;
}
};
int main(int argc, char *argv[])
{
LogLine log;
cout<< "Line One"<<endl;
log << "I'm " << 25 << " years old...."<<endl;
cout<<"Line Two"<<endl;
log << "I " << "Live in " << " Houston....";
return 0;
}
Current output:
Line One
Line Two
I'm 25 years old....
I Live in Houston....
Desired output:
Line One
I'm 25 years old....
Line Two
I Live in Houston....
I hope in each line of "log" be able to detect the end of that line and print out current message, and then clean itself. I know the reason of current output, but I can't figure out how should I modify my code to get desired output.("endl" can be missing)
Thanks a lot for any comments.
As described above...
When I understand you correctly, you want to detect the end of the statement, where log is used, and then append a std::endl.
My solution is similar to that one of #MarekR, but it forces a line break, when log is not rebound:
It does not detect "\n" and flushes it to std::cout, that would be contra productive on parallel std::cout calls.
#include <iostream>
#include <sstream>
using std::cout;
using std::endl;
class LogLine {
std::stringstream ss;
public:
LogLine(LogLine&&) noexcept = default;
LogLine() = default;
~LogLine()
{
if(ss && ss.peek() != -1){
cout << ss.str() << std::endl;
}
}
template <class T>
friend LogLine operator<<(LogLine& lhs, const T& thing)
{
lhs.ss << thing;
return std::move(lhs);
}
template <class T>
friend LogLine&& operator<<(LogLine && lhs, const T& thing)
{
lhs.ss << thing;
return std::move(lhs);
}
LogLine&& operator<<(std::ostream& (*manip)(std::ostream&))
{
manip(ss);
return std::move(*this);
}
};
int main()
{
LogLine forced;
cout << "Line One" << endl;
forced << "I'm " << 25 << " years old....";
cout << "Line Two" << endl;
LogLine() << "I " << "Live in " << " Houston...." << endl << endl << endl;
forced << "forced 2";
std::cout << "End of the sausage" << std::endl;
return 0;
}
That what happens here is: every call to operator<< creates a temporary, which steals the resources of the original structure. Therefore, when it is not rebound, the destructor gets called directly after the line, flushing the stringstream.
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;
I have the following class:
class BigNum
{
public:
BigNum(string StrNumber) : Number(std::move(StrNumber)) {}
BigNum(const char *StrNumber) : Number(string(StrNumber)) {}
~BigNum() = default;
struct
{
string HEX() { return Number + " - HEX"; }
string DEC() { return Number + " - DEC"; }
string BIN() { return Number + " - BIN"; }
}ToString;
private:
string Number;
};
And in the end I wand to elegantly access functions from that structure in the following way:
BigNum a = "1234";
cout << "a = " << a.ToString.DEC() << endl;
cout << "b = " << a.ToString.HEX() << endl;
The problem here is that I cannot access variable Number from my structure.
I know that something like this would solve my problem:
struct
{
string HEX(BigNum &parent) { return parent.Number + " - HEX"; }
...
}ToString;
The problem with this solution is that it is not comfortable to always pass a pointer to my instance.
What would be a solution in this case to have data in nested class and in the same time to keep calls as simple as a.ToString.DEC()?
In some way you have to give ToString a reference or a pointer to the BigNum object so you can access Number. How about something like this:
class BigNum
{
public:
BigNum(string StrNumber) : Number(std::move(StrNumber)) {}
BigNum(const char* StrNumber) : Number(string(StrNumber)) {}
~BigNum() = default;
// you can make the struct private so the type is not visible externally
struct ToStringType
{
private:
const BigNum& ref;
public:
ToStringType(const BigNum& r) : ref(r) {}
string HEX() { return ref.Number + " - HEX"; }
string DEC() { return ref.Number + " - DEC"; }
string BIN() { return ref.Number + " - BIN"; }
};
ToStringType ToString{ *this };
private:
string Number;
};
Irrelevant, but I would recommend to simply have separate ToStringHex, ToStringDec and ToStringBin functions. Saves on not storing a reference, plus the API is easier this way.
I don't see any rationale in the ToString struct.
Just leave the methods in BIGNUM and you are done.
However, for this specific application (changing the rendering style of your given objet in an ostream) I would let your object to be printed with the typical operator<< overaloading, and then modify the rendering style using io-manipulators, so that you will be able to:
cout << "a (DEC) = " << BigNum::DEC << a << endl;
cout << "a (HEX) = " << BigNum::HEX << a << endl;
A full fledged example:
#include <iostream>
#include <iomanip>
using namespace std;
class BigNum
{
public:
BigNum(string StrNumber) : Number(std::move(StrNumber)) {}
BigNum(const char *StrNumber) : Number(string(StrNumber)) {}
~BigNum() = default;
static std::ios_base& DEC(std::ios_base& os) {
os.iword(rendering_style_xalloc) = 0;
return os;
}
static std::ios_base& HEX(std::ios_base& os) {
os.iword(rendering_style_xalloc) = 1;
return os;
}
static std::ios_base& BIN(std::ios_base& os) {
os.iword(rendering_style_xalloc) = 2;
return os;
}
private:
static int rendering_style_xalloc;
string Number;
friend ostream &operator << (ostream &ostr, const BigNum &bignum);
};
int BigNum::rendering_style_xalloc = std::ios_base::xalloc();
ostream &operator << (ostream &os, const BigNum &bignum) {
switch (os.iword(BigNum::rendering_style_xalloc)) {
case 0:
os << bignum.Number << " - DEC";
break;
case 1:
os << bignum.Number << " - HEX";
break;
case 2:
os << bignum.Number << " - BIN";
break;
default:
os << bignum.Number << " - UNK";
break;
}
return os;
}
int main(int argc, char **argv)
{
BigNum a = "1234";
cout << BigNum::DEC << "a (DEC) = " << a << endl;
cout << BigNum::HEX << "a (HEX) = " << a << endl;
}
References:
https://en.cppreference.com/w/cpp/io/ios_base/iword
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;
}
class Vehicle
{
public:
//[...]
virtual std::ostream& ostreamOutput(std::ostream&) const; // virtual in order to use it for subclasse like cars, busses etc.
virtual double Speed() const; //returns the speed of a vehicle, is implemented in derived classes
private:
int Number
std::string Name
//[...]
protected:
int MaxSpeed; //these variables were also needed in the derived classes
};
std::ostream& Vehicle::ostreamOutput(std::ostream& os) const
{
os << std::resetiosflags(std::ios::right) << std::setiosflags(std::ios::left) << std::setfill(' ') << ""
<< std::setw(4) << Number
<< std::setw(9) << Name
<< std::setw(15) << Speed()
<< std::setw(5) << MaxSpeed
return os;
}
std::ostream& operator<<(std::ostream& os, const Vehicle& x)
{
x.ostreamOutput(os);
return os;
}
main() //I wanted to overload the "<<"-Operator in order to print the vehicle information without //a seperate function
{
Vehicle Vehicle1("Vehicle1", 80);
std::cout << Vehicle1 << std::endl;//the first shift-operator contains the error
}
I tried to overload the Shiftoperator but I get the error named:
"error c2679 binary ' ' no operator found which takes a right-hand operand of type".
The error occured in the first Shift Operator in the main function. I want to print Vehicle and its derived classes with the overloaded operator.
Can you explain the error to me? I really do not know how to correct this.
I fixed all the typos (missed semicolons) in your source, and here is a complete working example:
#include <iostream>
#include <iomanip>
using namespace std;
class Vehicle
{
public:
//[...]
Vehicle (const char* Name, int Number)
: Name (Name), Number (Number)
{}
virtual std::ostream& ostreamOutput(std::ostream&) const; // virtual in order to use it for subclasse like cars, busses etc.
virtual double Speed() const {return 0.;} //returns the speed of a vehicle, is implemented in derived classes
private:
// remove in-class initializers below if you need to avoid C++11
int Number = -1;
std::string Name = "not set";
//[...]
protected:
int MaxSpeed = 200; //these variables were also needed in the derived classes
};
std::ostream& Vehicle::ostreamOutput(std::ostream& os) const
{
os << std::resetiosflags(std::ios::right) << std::setiosflags(std::ios::left) << std::setfill(' ') << ""
<< std::setw(4) << Number
<< std::setw(9) << Name
<< std::setw(15) << Speed()
<< std::setw(5) << MaxSpeed;
return os;
}
std::ostream& operator<<(std::ostream& os, const Vehicle& x)
{
x.ostreamOutput(os);
return os;
}
int main() //I wanted to overload the "<<"-Operator in order to print the vehicle information without //a seperate function
{
Vehicle Vehicle1("Vehicle1", 80);
std::cout << Vehicle1 << std::endl;//the first shift-operator contains the error
}
Maybe you output some other variables for which operator<< is not defined. To debug this case, split the code from e.g. this:
os << std::resetiosflags(std::ios::right) << std::setiosflags(std::ios::left) << std::setfill(' ') << ""
<< std::setw(4) << Number
<< std::setw(9) << Name
<< std::setw(15) << Speed()
<< std::setw(5) << MaxSpeed;
to this:
os << std::resetiosflags(std::ios::right) << std::setiosflags(std::ios::left) << std::setfill(' ') << ""
<< std::setw(4) << Number;
os << std::setw(9) << Name;
os << std::setw(15) << Speed();
os << std::setw(5) << MaxSpeed;
This way you'll get the error message for the real line that is causing trouble. Otherwise you'll get the error message only for the first line, the compiler you use apparently does not distinguish the lines in this case.
Your code example contains only typos (Vehicle <-> Fahrzeug, ostreamAusgabe <-> ostreamOutput, semicolon after Speed() in ostreamOutput()). Overloaded operator<< should work fine.
Try to compile and launch this code:
class Vehicle
{
public:
Vehicle(const std::string& name, int num)
: Name(Name)
, Number(num)
, MaxSpeed(100)
{}
virtual std::ostream& ostreamOutput(std::ostream&) const;
virtual double Speed() const;
private:
int Number;
std::string Name;
protected:
int MaxSpeed;
};
double Vehicle::Speed() const
{
return 0.0;
}
std::ostream& Vehicle::ostreamOutput(std::ostream& os) const
{
os << std::resetiosflags(std::ios::right) << std::setiosflags(std::ios::left) << std::setfill(' ') << ""
<< std::setw(4) << Number
<< std::setw(9) << Name
<< std::setw(15) << Speed()
<< std::setw(5) << MaxSpeed;
return os;
}
std::ostream& operator<<(std::ostream& os, const Vehicle& x)
{
x.ostreamOutput(os);
return os;
}
int main()
{
Vehicle Vehicle1("Vehicle1", 80);
std::cout << Vehicle1 << std::endl;
return 0;
}