I have this struct:
struct sample {
int x;
};
and then I have this overload of operator<<:
std::ostream &operator<<(const std::ostream &os, const sample &s) {
if (s.x == 0)
return os << "zero";
else
return os << "not zero";
}
main:
int main() {
sample sam;
sam.x = 0;
std::cout << sam << std::endl;
sam.x = 1;
std::cout << sam << std::endl;
return 0;
}
But the compiler gives me this error:
Complile Error
What can I do?
You are right except for a small error in your operator signature:
std::ostream &operator<<(const std::ostream &os, const sample &s)
// ^^^^^ Problem
You mark the output stream as const but then modify it inside the function:
os << "zero";
and
os << "not zero";
Because
std::basic_ostream<CharT,Traits>::operator<< is not const.
So, remove that const and the code will work.
Related
This question already has an answer here:
C++ std::stringstream operator<< overloading
(1 answer)
Closed 3 years ago.
Here's my toy program. It fails to compile with error message " no operator << matches these operands". Any help will be appreciated.
struct foo {
std::string name;
};
std::ostringstream& operator<<(std::ostringstream& os, const foo& info)
{
os << info.name;
return os;
}
void insert(const foo& info)
{
std::ostringstream os;
os << "Inserted here " << info; // don't work here
}
int main()
{
foo f1;
f1.name = "Hello";
insert(f1);
}
The reason
os << "Inserted here " << info;
does not work is
os << "Inserted here "
returns a std::ostream&, not a std::ostringstream&.
Options:
Change your function to be use std::ostream instead of std::ostringstream.
std::ostream& operator<<(std::ostream& os, const foo& info) { ... }
Change how you use it. Use
os << "Inserted here ";
os << info;
I strongly recommend using the first option.
Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 5 years ago.
Improve this question
Problem:
From overloaded operator<<, cout will only print first bit:``"Hello guys, ", while the stream is multiple shifts << "Hello guys, " << "I can't get here!" << str << "\n"`.
My question is, why I only get the first bit of stream?
Code:
#include <iostream>
#include <sstream>
#include <string>
class Debug {
private:
std::stringstream stream;
public:
std::string str() const{
return stream.str();
}
std::stringstream& operator<<(std::string &s) {
stream << s;
std::cout << s;
return stream;
}
std::stringstream& operator<<(const char s[]) {
stream << s;
std::cout << s;
return stream;
}
};
std::ostream &operator<<(std::ostream &output, const Debug &d) {
output << d.str();
return output;
}
int main() {
Debug debug;
std::string str("Bad input");
debug << "Hello guys, " << "I can't get here!" << str << "\n";
std::cout <<"\n\n"<< debug;
std::cin.get();
return 0;
}
My question is, why I only get the first bit of stream?
as it was mentioned in the comments, any further calls after the 1st one of the Debug::operator<<() overload, will go to the overloaded operator of std::stringstream because you return a reference to that one.
What you probably want is a class that wraps a std::ostream interface like follows:
class Debug {
std::ostream& os_;
public:
Debug(std::ostream& os) : os_(os) {}
template<typename T>
Debug& operator<<(T val) {
// Intercept whatever you want to intercept here ...
os_ << val;
return *this;
}
};
This will ensure that the Debug::operator<<() overload is called repeatedly when the statement
debug << "Hello guys, " << "I can't get here!" << str << "\n";
is going to be executed.
int main() {
Debug debug(std::cout);
std::string str("Bad input");
debug << "Hello guys, " << "I can't get here!" << str << "\n";
return 0;
}
Outputs:
Hello guys, I can't get here!Bad input
See the Live Demo.
To collect the stuff at an inner stream, and just output the contents at a certain point, you can do it as follows:
#include <iostream>
#include <string>
#include <sstream>
class Debug {
std::ostringstream os_;
public:
template<typename T>
Debug& operator<<(T val) {
os_ << val;
return *this;
}
// Overload the operator<< to output the buffered stuff
friend std::ostream& operator<<(std::ostream& os, const Debug& debug) {
os << debug.os_.str();
return os;
}
};
int main() {
Debug debug;
std::string str("Bad input");
debug << "Hello guys, " << "I can't get here!" << str << "\n";
std::cout << debug;
return 0;
}
Another Live Demo.
Edit: Definition of class TF:
class TF {
std::vector<V4f> waypoints;
std::vector<int> densityWaypoints;
public:
std::size_t size() const { return waypoints.size(); }
friend std::ostream& operator<<(std::ostream& str, const TF& tf);
friend std::fstream& operator<<(std::fstream& str, const TF& tf);
// methods here
};
The question may steam from the fact that I don't understand streams, so that's probably a precondition.
Is it somehow possible to overload operator<<(std::ostream, T) so that when invoked in order to display the data structure on screen, it uses one overload, and when the data structure is written to a file, another one is used? Something like this probably:
std::ostream& operator<<(std::ostream& str, const TF& tf) {
for (std::size_t i = 0; i != tf.waypoints.size(); ++i) {
str << " { "
<< tf.densityWaypoints[i] << " : "
<< tf.waypoints[i][3] << " : "
<< tf.waypoints[i][0] << " , "
<< tf.waypoints[i][1] << " , "
<< tf.waypoints[i][2]
<< " } ";
}
str << "\n";
return str;
}
std::fstream& operator<<(std::fstream& str, const TF& tf) {
str << (int)tf.size();
for (std::size_t i = 0; i != tf.waypoints.size(); ++i) {
str << tf.densityWaypoints[i]
<< tf.waypoints[i][0]
<< tf.waypoints[i][1]
<< tf.waypoints[i][2]
<< tf.waypoints[i][3];
}
This doesn't compile with a strange error (I may be tired):
error: no match for ‘operator<<’ (operand types are ‘std::fstream {aka std::basic_fstream}’ and ‘int’)
The error occurs when I add the second operator<<() overload. The first one works fine. Tried both std::ofstream and std::fstream to the same result.
But I'm not sure if it's going to work either. Sure it's possible to define a function like int writeTF(std:fstream& str, const TF&tf), but that doesn't look C++ enough to me, not to mention the strange error that will potentially appear here, too.
I've seen code comparing the ostream's address to that of cout. I have mixed feelings about it, but it certainly worked:
std::ostream& operator<<(std::ostream& o, Foo const&)
{
if(&o == &std::cout) {
return o << "cout";
} else {
return o << "not_cout";
}
}
demo
Note that cout outputs to standard output, it's not the same thing as "the screen".
I'm a student and I studying c++.
This is my cpp code
int _tmain(int argc, _TCHAR* argv[])
{
CFood output;
output.whatFunc();
cout<<"my outputs"<<endl<<output<<endl;
return 0;
}
ostream& operator <<(ostream& outputStream, const CFood& output)
{
for(int i=0; i<2; i++)
{
outputStream <<"1 : "<<output.m_strName[i]<<" 2 : "<<output.m_servingSize[i]<<"g "<<"3 : "<<
output.m_calorie[i]<<"cal "<<"4 : "<<output.m_transFat[i]<<"g"<<endl;
}
return outputStream;
}
When I debug it, It work. But the end of the console, it gives me error message;;;
It says "An unhandled win32 exception occurred in work.exe [5796]"
My header filed is
class CFood
{
public:
CFood(void);
~CFood(void);
private:
string m_strName[7];
double m_servingSize[7];
double m_calorie[7];
double m_transFat[7];
public:
void whatFunc(void);
friend ostream& operator <<(ostream& outputStream,const CFood& output);
}
I think there is something wrong in my code..And I think it's CFood output;(Just thinking..)
Do you know why it has debug error?
++Sorry, I forgot the whatFunc(void)
This is code
void CFood::whatFunc(void) //
{
m_strName[0]="chicken";
m_strName[1]="rice";
m_strName[2]="meat";
m_strName[3]="strawberry";
m_strName[4]="apple";
m_strName[5]="water";
m_strName[6]="juice";
m_servingSize[0]=10;
m_servingSize[1]=20;
m_servingSize[2]=30;
m_servingSize[3]=40;
m_servingSize[4]=50;
m_servingSize[5]=60;
m_servingSize[6]=70;
m_calorie[0]=10.45;
m_calorie[1]=20.57;
m_calorie[2]=30.78;
m_calorie[3]=40.23;
m_calorie[4]=50.85;
m_calorie[5]=60.73;
m_calorie[6]=70.27;
m_transFat[0]=0.01;
m_transFat[1]=0.02;
m_transFat[2]=0.03;
m_transFat[3]=0.04;
m_transFat[4]=0.05;
m_transFat[5]=0.06;
m_transFat[6]=0.07;
}
Well its difficult to tell what exactly goes wrong without full source code. In my humble opinion, entire source lefts much to be desired. Placing obviously linked data in the bunch of the unlinked arrays with static size is not a very good pattern. Instead try something like that:
#include <iostream>
#include <vector>
#include <string>
#include <ostream>
struct CFoodItem{
std::string m_strName;
double m_servingSize;
double m_calorie;
double m_transFat;
};
class CFood
{
public:
void AddFoodItem(const CFoodItem& cItem);
friend std::ostream& operator <<(std::ostream& outputStream, const CFood& output);
private:
std::vector<CFoodItem> m_vItems;
};
std::ostream& operator <<(std::ostream& outputStream, const CFood& output)
{
for (auto i = output.m_vItems.begin(); i != output.m_vItems.end(); ++i)
{
outputStream << "1 : " << i->m_strName << " 2 : " << i->m_servingSize << "g " << "3 : " <<
i->m_calorie << "cal " << "4 : " << i->m_transFat << "g" << std::endl;
}
return (outputStream);
}
void CFood::AddFoodItem(const CFoodItem& cItem)
{
m_vItems.push_back(cItem);
}
int __cdecl main(void)
{
CFood output;
CFoodItem itm;
itm.m_strName = "some food";
itm.m_servingSize = 100500;
itm.m_calorie = 42;
itm.m_transFat = 42;
output.AddFoodItem(itm);
std::cout << "my outputs" << std::endl << output << std::endl;
return 0;
}
here is my function
ostream margain(std::string firstWord)
{
ostream x;
x << std::setw(20) << firstWord;
return x;
}
in main I want to use the function as follow
std::cout<< margain("start") << "````````````````````````````````````" << std::endl;
// print things out
//then
std::cout<< margain("End") << "````````````````````````````````````" << std::endl;
I get the output, start or end is not shown, and the return value is
0````````````````````````````````````
how can I fix it? and why?
Edit:
I know that the function is what causing that, because if I add this
cout << std::setw(20) << firstWord;
in the function, It prints right,
I fixed it, not the best way, but as
calling the function as
margain(std::cout, "End") <<
"~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~" << endl;
the function looks like
ostream& margain(ostream& stream, std::string firstWord)
{
stream << std::left << std::setw(10) << firstWord;
return stream;
}
anyone know better way?
You are printing the value of the ostream, not value of firstword. The ostream x in this case is an unopened stream, so it doesn't "do" anything. Because the compiler allows to conversion to either bool (C++11) or void * (before C++11), the "value" from that conversion is printed. Note that any operations on x will not affect cout.
The easiest solution, I would think is to actually add std::setw(20) to your output line:
std::cout<< std::setw(20 << "End" << "````````````````````````````````````" << std::endl;
The other choice would be to pass the std::cout to margain, and return the std::string, something like this:
std::string margain(ostream& x, const std::string& firstWord)
{
x << std::setw(20);
return firstWord;
}
then you could do:
std::cout<< margain(cout, "start") << "````````````````````````````````````" << std::endl;
But it's not exactly flexible or "neat".
The third option is of course to have a MarginString class:
class MarignString
{
private:
int margin;
std::string str;
public:
MarginString(int margin, std::string str) margin(margin), str(str) {}
operator std::string() { return str; }
friend std::ostream& operator(std::ostream& os, const MarginString& ms);
};
std::ostream& operator(std::ostream& os, const MarginString& ms)
{
os << std::setw(ms.margin) << ms.str;
return os;
}
...
std::cout<< MarginString(20, "start") << "````````````````````````````````````" << std::endl;
Note that this last way is probably not that great either... ;)
struct margin
{
margin(std::string word) : word(word) { }
friend std::ostream& operator <<(std::ostream& os, margin const& m)
{
return os << std::setw(20) << m.word;
}
private:
std::string word;
};