This question already has answers here:
How to properly overload the << operator for an ostream?
(6 answers)
What are the basic rules and idioms for operator overloading?
(8 answers)
Closed 2 years ago.
string var = "Hello";
cout << var << endl;
We get the result using only the object, without the help of a member variable. I want to implement a class that will work like string. For example:
class Test {
public:
int x = 3;
};
Test var2;
cout << var2 << endl;
How can I get implement the class so the cout line prints the value of x without referring to it?
The std::string class has operator << overloaded, that's why when you write:
std::string text = "hello!";
std::cout << var1 << std::endl; // calling std::string's overloaded operator <<
Prints the text held by it simply.
Thus, you need to overload the << operator for the class:
class Test {
int x = 3;
public:
friend std::ostream& operator<<(std::ostream& out, const Test& t) {
out << t.x;
return out;
}
}
// ...
Test var2;
std::cout << var2 << std::endl;
Related
This question already has answers here:
How do I print out the contents of a vector?
(31 answers)
Closed 3 years ago.
I would like to print the vector values in the friend overloaded operator <<.
The class is here:
#ifndef FOR_FUN_TESTCLASS_HPP
#define FOR_FUN_TESTCLASS_HPP
#include <utility>
#include <vector>
#include <string>
#include <ostream>
class TestClass {
public:
TestClass(uint32_t i, std::string s, std::vector<uint32_t> v) : i_(i), s_(std::move(s)), v_(std::move(v)) {}
friend std::ostream &operator<<(std::ostream &os, const TestClass &aClass) {
os << "i_: " << aClass.i_
<< " s_: " << aClass.s_
<< " v_: " << aClass.v_; //compiler error
return os;
}
private:
uint32_t i_ {0};
std::string s_;
std::vector<uint32_t> v_ {};
};
#endif //FOR_FUN_TESTCLASS_HPP
but when I invoke the main method, it does not compile
TestClass tc { 1, "one", {1,2,3}};
std::cout << tc << std::endl;
This is because the operator << does not know how to print the vector. I would like to stay in the method operator<< and print the vector. How is this done?
Error: error: no match for operator<< (operand types are
std::basic_ostream and const std::vector)
I don't want to iterate using the for operator, I am looking for a smarted solution, ie copy the vector contents in the ostream?
This will do the job:
friend std::ostream &operator<<(std::ostream &os, const TestClass &aClass) {
os << "i_: " << aClass.i_
<< " s_: " << aClass.s_
<< " v_: ";
for(auto it : aClass.v_)
os << it<<' ';
return os;
}
Live on Godbolt.
or with copy:
std::copy(aClass.v_.begin(), aClass.v_.end(),
std::ostream_iterator<uint32_t>(std::cout, ' '));
Live on Godbolt.
This question already has answers here:
Can I list-initialize a vector of move-only type?
(8 answers)
initializer_list and move semantics
(9 answers)
Closed 4 years ago.
UPD: The linked duplicate question do indeed resolve the issue. Thank you, everyone, for your suggestions.
Suppose I have the following class:
class NonCopyableInt {
public:
NonCopyableInt(const int &source) : data{source} {
}
NonCopyableInt(const NonCopyableInt &val) = delete;
void operator=(const NonCopyableInt &other) = delete;
NonCopyableInt(NonCopyableInt &&val) {
data = val.data;
}
int data;
};
Now, I'm using it this way:
template<typename T>
ostream &operator<<(ostream &os, const vector<T> &vec) {
for (const auto &v : vec) {
os << v << " ";
}
return os;
}
ostream &operator<<(ostream &os, const NonCopyableInt &v) {
os << v.data << " ";
return os;
}
int main(){
{
cout << "partial move" << endl;
vector<NonCopyableInt> v;
v.push_back(NonCopyableInt(1));
v.push_back(NonCopyableInt(2));
v.push_back(NonCopyableInt(3));
v.push_back({3});
vector<NonCopyableInt> vref;
cout << v << endl;
cout << vref << endl;
vref.push_back(move(v[0]));
v.clear();
cout << v << endl;
cout << vref << endl;
}
return 0;
}
This works perfectly fine and as expected. I am able to move objects between vectors without copying them. However, here is my question:
Why can I do this:
v.push_back({3});
But can't do this(causes the following compilation error: error: call to deleted constructor of 'NonCopyableInt'):
vector<NonCopyableInt> v{{1},{2}}
?
My guess is that when I call vector constructor, it can't accept element by rvalue or what?
Thank you.
This question already has answers here:
How to properly overload the << operator for an ostream?
(6 answers)
What are the basic rules and idioms for operator overloading?
(8 answers)
Closed 4 years ago.
Petroleum test = Set_Petroleum_values();
ofstream fuel("Fuel.txt");
{
fuel << test << " ";
fuel.close();
}
the set values function takes the users input and calls a default constructor for the test object.
My aim here is to somehow save the info that is being stored into this object however i am not sure how would i overload the "<<" operator when it comes to file handling.
and yes the aim is to store the object so that the info is maintained once different operations and functions are proceeded etc.
I think you should overload << operator in Petroleum class like this :
#include <iostream>
#include <fstream>
class Petroleum
{
public:
Petroleum(int v1,int v2) : val1(v1), val2(v2) {}
friend std::ostream& operator<<(std::ostream& os, const Petroleum& pet);
private:
int val1;
int val2;
};
std::ostream& operator<<(std::ostream& os, const Petroleum& pet)
{
return os << pet.val1 << " " << pet.val2 << std::endl;
}
int main()
{
Petroleum pet(2, 3);
std::ofstream fuel("Fuel.txt");
fuel << pet;
fuel.close();
}
This question already has answers here:
Why we need to return reference to istream/ostream while overloading >> and << operators?
(4 answers)
Closed 4 years ago.
class Fruit
{
private:
std::string m_name;
std::string m_color;
public:
Fruit(std::string name, std::string color)
: m_name(name), m_color(color)
{
}
std::string getName() const { return m_name; }
std::string getColor() const { return m_color; }
};
class Apple : public Fruit
{
private:
double m_fiber;
public:
Apple(std::string name, std::string color, double fiber)
:Fruit(name, color), m_fiber(fiber)
{
}
double getFiber() const { return m_fiber; }
friend std::ostream& operator<<(std::ostream &out, const Apple &a)
{
out << "Apple (" << a.getName() << ", " << a.getColor() << ", " << a.getFiber() << ")\n";
return out;
}
};
My question is regarding the friend function with the overloaded operator '<<'.
I need to understand some basics which are troubling me, for one why does the function return a reference to a stream ?
The returned lvalue ref to the stream means that you can reuse the returned value as an lvalue which references the returned object so you can chain multiple insertion operations together. For example,
std::cout << Apple("foo", "red", 3.4) << Apple("bar", "red", 5.5);
or perhaps better seen in terms of precedence as
(std::cout << Apple("foo", "red", 3.4)) << Apple("bar", "red", 5.5);
as opposed to, if you didn't return an lvalue ref, and perhaps just returned void, only the following would work:
std::cout << Apple("foo", "red", 3.4)
If you just returned std::ostream instead of std::ostream&, then an attempt to copy of the stream object would be attempted, and fail at compilation b.c. the copy ctor is deleted as shown here http://www.cplusplus.com/reference/ostream/ostream/ostream/.
I am trying to understand how this program works. i am new to c++ templates.
Can someone explain why we need the following function?
friend std::ostream &operator <<(std::ostream &os, const Temp &temp)
It seems to work only for the string template.
Also, what does the function operator T() {return val;} do?
#include <iostream>
#include<string>
template <typename T>
class Temp {
friend std::ostream &operator <<(std::ostream &os, const Temp &temp) {
os << temp.val;
return os;
}
public:
Temp(T val) : val(val) {}
operator T() {return val;}
public:
T val;
};
usage example:
#include <iostream>
#include<string>
#include "temp2.h"
using namespace std;
int main() {
temp<int> si = 10;
cout << "si: " << si << endl;
si = si + 2;
cout << "After si = si + 2: " << si << endl;
Temp<double> si2 = 15.5;
cout << "si: " << si2 << endl;
si2 = si2 + 2.3;
cout << "After si = si + 2: " << si2 << endl;
Temp<string> ss = string("Hello");
cout << "ss: " << ss << endl;
ss = string(ss).substr(1);
cout << "After ss = si.substr(1): " << ss << endl;
return 0;
}
It's not that the operator << is really needed, but it's convenient to have it when using output streams. Also, the operator needs to access the inner value of the Temp class, hence the friend qualifier. Without it, the class would have to expose the inner value val to the external world somehow (the usual way is to make a public read only method), and this create a maintenance problem, since future evolutions of the class would have to keep supporting the method, even if the class internals change.
In other words, having the << operator declared as friend to the class prevents the implementation details to leak out to the rest of the world.
That said, the T() operator provides almost the service of the hypothetic read only method that I described above, but with replacing the read only part by copying the val field. Basically, it's a cast operator allowing to implicitely cast a Temp value to a T value. The << operator could have been implemented using that cast operator, and thus without the need of the friend qualifier. However, certainly for efficiency concerns, the friend qualifier has been kept to avoid the overhead of copying val.
Regarding the implementation of the << operator, we can see that it rely on the same operator defined for the T typename. Any type having this operator defined for should work without problem with this template.