I have the following class(prototipe):
class Token
{
public:
//members, etc.
friend std::stringstream& operator<< (std::stringstream &out, Token &t);
};
And the operator is implemented like this:
std::stringstream & operator<< (std::stringstream &out, Token &t)
{
out << t.getValue(); //class public method
return out;
}
Now, I'm trying to use it like this:
std::stringstream out;
Token t;
//initialization, etc.
out << t;
And VS gives me error, saying that there is no match for << operator. What am I wrong in?
std::stringstream & operator<< (std::stringstream &out, Token &t)
should be
std::ostream & operator<< (std::ostream &out, Token const &t)
Related
Reading some documentation online I found that istream class was part of C++ long before the string class was added. So the istream design recognizes basic C++ types such as double and int, but it is ignorant of the string type. Therefore, there are istream class methods for processing double and int and other basic types, but there are no istream class methods for processing string objects.
My question is if there are no istream class methods for processing string objects, why this program works and how ?
#include <iostream>
int main(void)
{
std::string str;
std::cin >> str;
std::cout << str << std::endl;
return 0;
}
This is possible with the use operator overloading. As shown in the below example, you can create your own class and overload operator>> and operator<<.
#include <iostream>
class Number
{
//overload operator<< so that we can use std::cout<<
friend std::ostream& operator<<(std::ostream &os, const Number& num);
//overload operator>> so that we can use std::cin>>
friend std::istream &operator>>(std::istream &is, Number &obj);
int m_value = 0;
public:
Number(int value = 0);
};
Number::Number(int value): m_value(value)
{
}
std::ostream& operator<<(std::ostream &os, const Number& num)
{
os << num.m_value;
return os;
}
std::istream &operator>>(std::istream &is, Number &obj)
{
is >> obj.m_value;
if (is) // check that the inputs succeeded
{
;//do something
}
else
{
obj = Number(); // input failed: give the object the default state
}
return is;
}
int main()
{
Number a{ 10 };
std::cout << a << std::endl; //this will print 10
std::cin >> a; //this will take input from user
std::cout << a << std::endl; //this will print whatever number (m_value) the user entered above
return 0;
}
By overloading operator>> and operator<<, this allows us to write std::cin >> a and std::cout << a in the above program.
Similar to the Number class shown above, the std::string class also makes use of operator overloading. In particular, std::string overloads operator>> and operator<<, allowing us to write std::cin >> str and std::cout << str, as you did in your example.
Because std::string overload the >> and << operator to return the type std::istream and std::ostream
How they overload it, you can look in this link that Mat gives.
You can create your own class and overload operators, too. Here is an example:
class MyClass
{
int numberOne;
double numberTwo;
public:
friend std::ostream& operator<<(std::ostream &out, const MyClass& myClass);
friend std::istream& operator>> (std::istream& in, MyClass& myClass);
};
// Since operator<< is a friend of the MyClass class, we can access MyClass's members directly.
std::ostream& operator<<(std::ostream &out, const MyClass& myClass)
{
out << myClass.numberOne << ' ' << myClass.numberTwo;
return os;
}
// Since operator>> is a friend of the MyClass class, we can access MyClass's members directly.
std::istream& operator>> (std::istream& in, MyClass& myClass)
{
in >> myClass.numberOne;
in >> myClass.numberTwo;
return in;
}
int main()
{
MyClass myClass;
std::cin >> myClass;
std::cout << myClass;
}
Because of operator overloading.
In your case, including <iostream> will include <string>, a specialization of std::basic_string. And std::basic_string has the non-member functions operator<< and operator>> defined.
Similarly, you can also overload operator<< and operator>> for your own custom types.
I have a simple C++ class, which I'm trying to add stream operators to, so it can be used with cout and cin
#include <iostream>
namespace testing_namespace {
class test {
friend std::ostream &operator<<(std::ostream &os, const test &o);
friend std::istream &operator>>(std::istream &is, test &o);
public:
void doThing();
private:
int member;
};
}
This is the implementation file:
std::ostream &operator<<(std::ostream &os, const testing_namespace::test &o) {
return os << o.member;
}
std::istream &operator>>(std::istream &is, testing_namespace::test &o) {
return is >> o.member;
}
void testing_namespace::test::doThing() {
std::cout << member << " thing" << std::endl;
}
I'm getting an error on compilation:
In function 'std::ostream& operator<<(std::ostream&, const testing_namespace::test&)':
test.cpp:8:20: error: 'int testing_namespace::test::member' is private within this context
return os << o.member;
with a similar error for operator>>. The doThing method compiles with no issues.
I'm not sure what I'm missing here - shouldn't friend functions be able to access the private members of the class test?
You need to define those functions under the namespace too. When you do that, you can omit the name of the namespace from test.
namespace testing_namespace
{
std::ostream &operator<<(std::ostream &os, const test &o) {
return os << o.member;
}
std::istream &operator>>(std::istream &is, test &o) {
return is >> o.member;
}
}
This is what I tried so far:
class Fahrzeug
{
public:
std::string Id() const;
void Id(const std::string &id);
friend std::ostream& operator<< (std::ostream &out, const Fahrzeug &fzg)
{
out << Id();
return out;
}
private:
struct DatenImpl;
boost::scoped_ptr<DatenImpl> _datenImpl;
};
This yields a compiler error:
error C2352: Id() - illegal call of non-static member function
How can I implement the ostream operator<< for a "pimpled" class?
Your definition should be:
friend std::ostream& operator<< (std::ostream &out, const Fahrzeug &fzg)
{
out << fzg.Id(); // <--- qualify call to Id()
return out;
}
The operator is not a class member, although defined inside the class.
How do I overload the << operator? From the error I am getting, it seems that std::cout doesn't know how to use <<.
This is in a class:
// uint64_t UPPER, LOWER;
std::ostream & operator<<(std::ostream & stream){
if (UPPER)
stream << UPPER;
stream << LOWER;
return stream;
}
I am getting error: no match for 'operator<<' in 'std::cout << test' which doesn't seem to make sense.
edit:
Neither this:
std::ostream & operator<<(std::ostream & stream, uint128_t const & val){
if (val.upper())
stream << val.upper();
stream << val.lower();
return stream;
}
nor this:
std::ostream & operator<<(std::ostream & stream, uint128_t val){
if (val.upper())
stream << val.upper();
stream << val.lower();
return stream;
}
is changing the error.
The << operator takes two arguments, a left hand side, and a right hand side. Therefore you have to define the function with two parameters:
std::ostream operator<<(std::ostream &os, const MyClass &obj);
And you have to define it outside of your class definition, as far as I can remember. Inside of the class definition you can only have operators that take that class as the left hand side.
You typically want the operator<<() overload to be a 'free function' (outside of your class) so it can bind to the stream naturally:
// this is outside your class definition
std::ostream& operator<<(std::ostream& os, const myclass& rhs)
{
// whatever...
return os;
}
Then inside your class you declare it a friend if necessary so it can get to the class internals:
friend std::ostream& operator<<(std::ostream& os, const myclass& rhs);
An alternative to having this be a friend (which some people consider to be breaking encapsulation) is to have a public function in your class that will output itself to a stream and call that in your operator<<() overload:
// inside class myclass - a normal public member function
std::ostream& dump( std::ostream& os)
{
os << some_class_member;
// ...
return os;
}
// now, the `operator<<()` overload doesn't need to be a friend
// this is still outside your class definition
std::ostream& operator<<(std::ostream& os, const myclass& rhs)
{
return rhs.dump(os);
}
operator<< outside a class requires two arguments:
std::ostream& operator<<(std::ostream& stream, type_you_want_output const& thing)
why does
void operator<<(ostream out, Test &t);
return an error whereas
void operator<<(ostream &out, Test &t);
does not ?
Because you cannot copy streams, you have to pass them per reference.
Note that the canonical form of operator<< is this:
std::ostream& operator<<(std::ostream& out, const Test &t)
{
// write t into out
return out;
}
returning the stream is important so that you can string output together:
std::cout << Test() << '\n';