I've been working on this school assignment. The assignment told us to make an object which had it's output operator ( << ) overloaded.
Here's my code:
#include <ostream>
using namespace std;
template <class T>
class CustomObject {
string print() {
string text = "";
for (int i = 0; i < num_items(); i++) {
text += queue[i];
text += " | \n";
}
return text;
}
friend std::ostream& operator <<(std::ostream &output, CustomObject &q) {
output << "" << q.print();
return output;
}
}
So I instantiate this object like this:
CustomObject<int> co();
and call its output method:
std::cout << co();
Which would inevitably call the print method, and return the string to the default output stream.
But, there's no visible output in my console/debugger.
What am I missing here?
PS this is not the complete class, it's generic because of several other methods and functionality that is not necessary to be shown here.
PPS the num_items() and queue variables are part of said rest, this class is a PriorityQueue object. So, queue is an array of the specified type (hence the generic declaration) and num_items() just returns the count of the array.
CustomObject<int> co();
That's a function declaration. Leave out the parenthesis.
std::cout << co();
Why are you appling operator() to co? Again, leave out the parenthesis. This should work:
CustomObject<int> co;
std::cout << co;
Alas, building and returning a string from a print method is hardly idiomatic C++. Here is what I would do:
template <typename T>
class CustomObject
{
// ...
public:
void print(std::ostream& os) const
{
for (int i = 0; i != num_items(); ++i)
{
os << queue[i] << " | \n";
}
}
};
std::ostream& operator<<(std::ostream& os, const CustomObject& object)
{
object.print(os);
return os;
}
If you want to be able to print temporary objects a well, you should make the parameter a const reference:
CustomObject const& q)
Related
This question stems from a larger code I am working on but hopefully I can break it down to simplify:
Say I have two classes, one which holds 2 integer variables, and another which contains a vector that holds the first class
class TwoInts {
int num1;
int num2;
}
class NumHold {
std::vector<TwoInts> numVector;
}
How would I go about printing my numHold class exactly? I know I would have to provide an overloaded stream operator
std::ostream &operator<< (std::ostream &out, const NumHold &myNumHold){;}
But I'm a little confused as to the syntax regarding how I would print out these integers from the vector. I also understand that in order for the stream operator to work I would have to add it to my class as a friend, I just wanted to keep my NumHold class as simplified as possible for the examples sake. Hopefully this was clear enough of an explanation, any help is appreciated
Treat out how you would treat std::cout, then return it at the end of the function:
std::ostream& operator<<(std::ostream& out, const NumHold &myNumHold){
//one possible output format
for(const auto& twoInt : myNumHold.numVector){
out << twoInt.num1 << ", " << twoInt.num2 << '\n'; //pretend out is std::cout
}
return out; //don't forget to return it at the end
}
If appropriate, declare the overload as a friend function within the NumHold class:
#include<iostream>
class NumHold {
private:
std::vector<TwoInts> numVector;
public:
//friend operator overload declaration
friend std::ostream& operator<<(std::ostream& out, const NumHold& myNumHold);
};
In your example, it is appropriate, as the overload function accesses private variables.
You need to be able to access the members of each TwoInts in order to print them. One way to do this is to make them public.
class TwoInts {
public: //lets NumHold access variables to print
int num1;
int num2;
};
class NumHold {
public:
std::vector<TwoInts> numVector;
friend std::ostream& operator << (std::ostream& out, const NumHold& myNumHold) {
for (const TwoInts& ti : myNumHold.numVector) {
out << "(" << ti.num1 << ", " << ti.num2 << ")" << std::endl;
}
return out;
}
};
You can also consider adding printing methods to your classes:
#include<iostream>
class TwoInts {
private:
int num1;
int num2;
public:
void printnum1(){
std::cout << num1;
}
void printnum2(){
std::cout << num2;
}
}
class NumHold {
private:
std::vector<TwoInts> numVector;
public:
//this function prints the private attributes of the class
void printnumVector(){
for (int i = 0; i < numVector.size(); i++){
std::cout << numVector[i].printnum1() << " " << numVector[i].printnum2() << std::endl;
}
}
};
New to C++ here. Lets say I have a struct defined as:
struct Item {
string name;
}
In C++, is there a way where I can get the value of name by just calling the object?
Item item;
item.name = "Andy"
cout << item; // --> Output: "Andy"
Thanks!
You need to overload the stream insertion operator operator<< for Item type.
#include <iostream>
#include <string>
struct Item {
std::string name;
friend std::ostream& operator<<(std::ostream& stream, const Item& obj);
};
std::ostream& operator<<(std::ostream& stream, const Item& obj) {
// Feel free to extend this function to print what you like.
// You can even do something like 'stream << "Item(" << obj.name << ")";'.
// The implementation is upto you as long as you return the stream object.
stream << obj.name;
return stream;
}
int main() {
Item it{"Item1"};
std::cout << it << std::endl;
}
Try it out yourself
More references on the topic:
reference 1
reference 2
So essentially I have a private std::vector<std::string> alloc in class A which has some manipulation etc done on it by public method std::vector<std::string> allocMethod() and this method then does return alloc. The method is called in class B
In class B I want to print the return value of allocMethod, i.e the alloc vector. This is what I have
std::cout << A.allocMethod();
I know that normally one would use some sort of interator and loop to print out a vector but I don't think I can do that as it is a functions return value being printed not actually a vector.
Note: I reeaaally don't wan't to have to just print out the vector in class A.
Is there a way to output the std::vector<string> result as shown above?
"Note: I reeaaally don't wan't to have to just print out the vector in class A."
As you want to use this repeatedly it might be worth it to provide an appropriate output operator overload for std::vector<std::string>
std::ostream& operator<<(std::ostream& os,const std::vector<std::string>>& vs) {
for (const auto& s : vs) {
os << s << " ";
}
return os;
}
That should allow for just calling
std::cout << A.allocMethod();
You can even try a more generic overload
template<typename T>
std::ostream& operator<<(std::ostream& os,const std::vector<T>>& vs) {
for (const auto& s : vs) {
os << s << " ";
}
return os;
}
Contrary to your believe, you can print the vector by iterating over it although it is a temporary using the C++11 for-loop like this:
for (const auto& i : A.allocMethod())
std::cout << i << '\n';
You can just store the return value and then iterate over it. Like this:
std::vector<std::string> result = allocMethod();
for (std::size_t i = 0; i < result.size(); ++i)
{
std::cout << result[i];
}
Given a class
class ostreamWrapper
{
private:
ostream * str;
public:
ostreamWrapper operator << (const char *);
}
where ostream * str will point to std::cout and ostreamWrapper operator << (const char *) sends the given text to the wrapped ostream str.
In this case, I can only instance << "const char * text" and no other printable data. Unlike directly <<ing a std::cout or std::cerr.
How can the operator method be implemented so it accepts any type of data just as std::cout or std::cerr directly do?
First, write a public operator<< template so it can accept any type and simply forward it to the wrapped ostream.
template <class T>
ostreamWrapper& operator<<(T&& x) {
*str << std::forward<T>(x);
return *this;
}
Second, in order to accept insertion of stream manipulator templates such as std::endl, add a second public operator<< that specifically accepts manipulators intended for the wrapped ostream:
ostreamWrapper& operator<<(ostream& (*manip)(ostream&)) {
*str << manip;
return *this;
}
Omitting the second overload will cause insertion of overloaded manipulators or manipulator templates to fail with "ambiguous overload" or similar error messages.
See an example of the proposed implementation, it would deduce the template parameter type and print accordingly, if you could use C++11 see #Brian answer:
#include <iostream>
using namespace std;
class ostreamWrapper {
private:
ostream* str;
public:
ostreamWrapper(ostream* str_v) : str(str_v) {}
template <typename T>
ostreamWrapper& operator<<(const T& t) {
if (str)
*str << t;
return *this;
}
};
int main() {
ostreamWrapper osw(&std::cout);
osw << 1 << " texto " << std::string(" otro texto ") << 1.2345;
return 0;
}
Can the following code (I only kept the relevant part) be converted to use a static member function rather than a friend free function? If not, why not? I tried to convert it to use a static member function in multiple different ways and failed (kept getting different compiler errors for different variations), but I gathered from the answer to this question that you could use either one to do the same things. Is this not technically true due to some property of C++ syntax? Where am I going wrong here?
class Tape {
public:
friend std::ostream &operator<<(std::ostream &, Tape &);
private:
char blank;
size_t head;
std::string tape;
}
std::ostream &operator<<(std::ostream &out, Tape &tape) {
out << tape.tape << std::endl;
for (size_t i = 0; i < tape.head; i++)
out << ' ';
out << '^' << std::endl;
return out;
}
According to the C++ Standard
6 An operator function shall either be a non-static member function or
be a non-member function and have at least one parameter whose type is
a class, a reference to a class, an enumeration, or a reference to an
enumeration.
So you may not define operator << as a static mamber function of the class.
Nevertheless inside the definition of the operator you may use static member functions.
For example
#include <iostream>
class A
{
private:
int x = 10;
public:
static std::ostream & out( std::ostream &os, const A &a )
{
return ( os << a.x );
}
};
std::ostream & operator <<( std::ostream &os, const A &a )
{
return ( A::out( os, a ) );
}
int main()
{
A a;
std::cout << a << std::endl;
return 0;
}
Opposite to C++ in C# operator functions are defined as static.:)
Since the std::ostream argument is the left hand side of the operator, it can't be a member of your class (static or otherwise).
So it has to be a free function, because you can't add members to std::ostream.
It doesn't have to be a friend though, it could instead call a public member.
I personally prefer this method, as it doesn't expose anything to the outside.
class Tape {
public:
void print(std::ostream &out) const
{
out << tape << std::endl;
for (size_t i = 0; i < head; i++)
out << ' ';
out << '^' << std::endl;
}
};
std::ostream& operator<<(std::ostream &out, const Tape &tape)
{
tape.print(out);
return out;
}