I have a problem with return type of my class operator overload.
I want to return the same object when operator does it's thing so i can continue the sequence.
I have a class Console and this code:
template <class out>
Console& Console::operator<<(const out &data)
{
std::stringstream ss;
ss << data;
output += ss.str();
return this;
}
but the error I get is
UI_Console.cpp: In member function 'vui::Console&
vui::Console::operator<<(const out&)': UI_Console.cpp:13:12: error:
invalid initialization of non-const reference of type 'vui::Console&'
from an rvalue of type 'vui::Console*'
I can make it void but when I call an operator on object like:
Console obj;
obj << "Hello" << "World\n";
I get an error that the second operator doesn't know what to do. How can I make it work?
You return this as a pointer. Your function declaration requires a reference, thus you need return *this;.
Related
How to overload an operator<< with a function as parameter, like std::endl does for std::cout?
In my project, I need to do this. For example, in the following code:
CSampleClass test;
test << CSampleClass::foo; // foo is function
I write code as following but it causes an error:
In the class header file:
CSampleClass& foo(CSampleClass& c);
CSampleClass& operator << (CSampleClass& (*pf)(CSampleClass&));
In the class source file:
CSampleClass& CSampleClass::foo(CSampleClass& c)
{
// do some thing
// for example set a variable in CSample class object
// c.samevar = 0;
return *this;
}
CSampleClass& CSampleClass::operator << (CSampleClass& (*pf)(CSampleClass&))
{
return *pf(*this);
}
In order to use foo with overload
CSampleClass& operator << (CSampleClass& (*pf)(CSampleClass&));
it needs to be a non-member function or a static member function.
Non-static member functions are not like regular functions. Your operator should be declared like this
CSampleClass& operator << (CSampleClass& (CSampleClass::*pf)(CSampleClass&));
CSampleClass& (CSampleClass::*pf)(CSampleClass&) is a pointer to a member function (of the class CSampleClass).
I'm writing a c++ linked list using ostream operator, and I am stuck.
What have I done wrong?
// Train class
class Car{
public:
void print(ostream&) const;
friend std::ostream &operator<<(std::ostream&, const Car&);
};
void Car::print(ostream& out) const{
out << "OK" << endl;
}
ostream& operator<<(ostream& os, const Car& car){
os << car->print(os);
return os;
}
error: base operand of ‘->’ has non-pointer type ‘const Car’
make: ***[Car.o] Error 1
Things I have tried:
1) os << car->print(*os);
2) os << car.print(os); // it gets worse
Things I have tried:
1) os << car->print(*os);
base operand of ‘->’ has non-pointer type ‘const Car’
The error should be quite clear. You've applied the indirecting member access operator -> on a non-pointer (of a type that doesn't overload that operator). That's something that you can not do. Presumably, you intended to call Car::print instead. That can be done using the regular member access operator .
ostream& os
print(*os)
This is wrong. There is no indirection operator for ostream. Since print accepts a ostream& as an argument, presumably you intended to pass os to the function instead.
void Car::print
Car::print returns void i.e. it doesn't return any value. Yet, you insert the return value into the stream. You cannot insert void into a stream. If you intend to return something from the function, then change the return type to whatever you intended to insert into the stream. Or, if you only intend to insert things into the stream within the function, then simply don't insert the return value of the function:
When we fix all three of these things, we end up with
car.print(os);
Finally, Car::print isn't declared in the definition of Car. All member functions must be declared in the class definition. The declaration should look like this:
class Car{
public:
void print(ostream& out) const;
// ...
}
What do you call function that follows a member function and modifies the return value and how do I write one?
In other words how do I successfully write:
std::cout << box.getVolume().inCubicFeet();
std::cout << box.getVolume().inCubicCentimeters();
For that to work getVolume() needs to return an object of type Volume ( or even a reference to an object of type Volume &), so that whatever method follows you are able to invoke it on said object.
For instance:
class Volume{
...
int inCubicFeet() const {
//convert it and return it
}
int inCubicCentimeters() const {
//convert it and return it
}
};
class Box{
Volume v; //volume object that is initialized somewhere
//(either in the constructor of Box or in a method like setVolume)
...
Volume const& getVolume() const {
return v;
}
};
box.getVolume() needs to return an object of a class for which a function inCubicFeet() is defined which returns a value for which std::ostream has an overloaded << operator (although you are allowed to define your own overloads). For that second part, a double would suffice.
It is called "member function of the return type". There is nothing special about those methods. The code could be written like this:
const Volume& v = box.getVolume(); // my guess on what the return type is
std::cout << v.inCubicFeet();
I'm trying to write a std::ostream operator<< for a class. I have a function that (taking advantage of ROV) returns instances of that class.
My operator works when I assign the result of that function call to a local variable, and then pass the local into operator <<, but NOT when I pass the result in directly. What's going on here?
Simplified standalone example (test.cpp):
#include <iostream>
template <class T>
class AnObject{
public:
AnObject(T value) : m_value(value) {}
T getValue(){ return m_value; }
protected:
T m_value;
};
template <class T>
std::ostream & operator<<(std::ostream& os, AnObject<T> & obj )
{
os << obj.getValue();
return os;
}
AnObject<int> getObject()
{
return AnObject<int>(5);
}
int main(int argc, char**argv)
{
// This doesn't compile
std::cout << getObject() << std::endl;
// This does....
//auto obj = getObject();
//std::cout << obj << std::endl;
}
Compiler command (g++ version 4.8.4 on Ubuntu):
g++ -std=c++11 test.cpp
Error:
test.cpp:26:26: error: cannot bind ‘std::ostream {aka std::basic_ostream<char>}’ lvalue to ‘std::basic_ostream<char>&&’
AnObject<int> getObject()
{
return AnObject<int>(5);
}
This function above is your error. Why? Because it's used as a part of an rvalue expression, which is not an lvalue.
In C++, lvalues sort of represent the "containers" that hold actual values. rvalues refer to these "actual" values. A good example:
int i = 5; // i is the lvalue, 5 is the rvalue.
// 5 by itself is not a variable, but i has the rvalue of 5 but the lvalue of i.
The << operators wants an actual object instead of a value of it--in other words, it should have a "home" and be stored somewhere.
So either make another overload that takes a &&, which means it can take values that may not "live" anywhere (e.g. expressions) or require the values that come in to be lvalues (references to real objects). A good option is to use const T&, to which rvalues can be cast.
When I try to compile the following code, the compiler generates a long paragraph of error message, saying something like " no match for ‘operator<<’ in ‘std::cout << a.A::operator++(0)’ " ... "candidates are...."
But if I change the type of the second parameter of operator<< to "const A&" or simply "A", it magically compiles.
Why does this change work? Does the c++ standard force the type of the second parameter to be either const T& or T when << is overloaded? Or there are some other reasons?
#include <iostream>
using namespace std;
class A
{
public:
A operator++(int) { return A(); }
};
ostream& operator<<(ostream& os, A& a)
{
return os;
}
int main()
{
A a;
cout << a++;
return 0;
}
What you're missing is that operator++ returns a temporary value. It has to increment the value yet still return the original, so what it does is save off a copy of the original, then increment it, then return the original value copy.
This copy is return as an unnamed temporary, and the language states that such values can't be bound to non-const references (as your parameter). You don't want to pass to an output function as non-const reference anyway as if you mutated the value during output your users would be extremely disappointed.
You can't initialize non-const references with r-values. Your operator++ returns an r-value. There are two ways:
Define you << operator as
ostream& operator<<(ostream& os, const A& a)
or pass l-value
A b = a++;
cout << b;