C++ Struct Default Call Value - c++

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

Related

(c++14) operator<< overloading not working as expected from vector of smart pointers

I am doing something wrong here, but i am not sure what. I expect the output of the program to be "tacos!", but I am getting a memory location instead.
I am trying to use C++14 features. In this program I am attempting to use smart pointers and overload the << operator.
A tacoCalendar object holds a vector smart pointers for tacoTuesdays objects, of which one is created on tacoCalendar's initialization. The cout << month.my_tacoTuesdays.at(0).get(); line should get send the pointee of the first smart pointer of the tacoTuesdays vector in month to the friend function friend std::ostream& operator<<(std::ostream& os, const tacoTuesdays& tt); resulting in "tacos!" being returned and sent to std::cout.
Code:
#include <iostream>
#include <vector>
#include <string>
#include <memory>
class tacoTuesdays {
public:
tacoTuesdays(int i) {
_i = i;
}
friend std::ostream& operator<<(std::ostream& os, const tacoTuesdays& tt);
private:
int _i;
};
std::ostream& operator<<(std::ostream& os, const tacoTuesdays& tt) {
std::string str_out = "tacos!";
os << str_out;
return os;
}
typedef std::shared_ptr< tacoTuesdays > smart_tacoTuesdays_t;
class tacoCalendar {
public:
std::vector<smart_tacoTuesdays_t> my_tacoTuesdays;
tacoCalendar(int i) {
smart_tacoTuesdays_t tt(new tacoTuesdays(i));
my_tacoTuesdays.push_back(tt);
}
~tacoCalendar() {
}
private:
};
int main(int argc, char **argv) {
using namespace std;
tacoCalendar month(2);
cout << *month.my_tacoTuesdays.at(0).get();
return 0;
}
std::shared_ptr<T>::get() returns a T*, but your operator<< overload (correctly) takes a reference rather than a pointer.
Change
cout << month.my_tacoTuesdays.at(0).get();
to
cout << *month.my_tacoTuesdays.at(0);
Or if any shared_ptr instance can be null,
if (auto* p = month.my_tacoTuesdays.at(0).get()) {
cout << *p;
}
Pay attention to the type of cout:
cout << month.my_tacoTuesdays.at(0).get();
It is printing the std::vector<std::shared_ptr<tacoTuesdays>>::at(0).get(0), which is a pointer tacoTuesdays*, so cout print the raw pointer address for you.
To get what you want, you should pass tacoTuesdays's const reference, like this:
cout << *month.my_tacoTuesdays.at(0);

Storing values in a container

I'm trying to read two values from a file and store them in my class called God. God has two data members, name and mythology. I wish to store the values in a list<God> (the god and its respective mythology) and then print them out. Here is my code so far:
#include <iostream>
#include <fstream>
#include <list>
#include <string>
using namespace std;
class God {
string name;
string mythology;
public:
God(string& a, string& b) {
name=a;
mythology =b;
}
friend ostream& operator<<( ostream& os,const God&);
};
void read_gods(list<God>& s) {
string gname, gmyth;
//reading values from file
ifstream inFile;
inFile.open("gods.txt");
while(!inFile.eof()) {
inFile >> gname >> gmyth ;
s.push_back(God(gname, gmyth));
}
}
ostream& operator<<( ostream& os,const God& god) {
return os << god.name << god.mythology;
}
int main() {
//container:
list<God> Godmyth;
read_gods(Godmyth);
cout << Godmyth;
return 0;
}
If for example I read in Zeus, Greek then how would I be able to access them?
The error I'm receiving is:
error: cannot bind 'std::ostream {aka std::basic_ostream<char>}' lvalue to 'std::basic_ostream<char>&&'|
You should write either operator << or some member function for class God that outputs its data members.
For example
class God
{
public:
std::ostream & out( std::ostream &os ) const
{
return os << name << ": " << mythology;
}
//...
};
Or
class God
{
public:
friend std::ostream & operator <<( std::ostream &, const God & );
//...
};
std::ostream & operator <<( std::ostream &os, const God &god )
{
return os << god.name << ": " << god.mythology;
}
In this case instead of invalid statement
cout << Godmyth << endl;
you could write
for ( const God &god : Godmyth ) std::cout << god << std::endl;
Or if you simply want to access the data members then you should write getters.
For example
class God
{
public:
std::string GetName() const { return name; }
std::string GetMythology() const { return mythology; }
//...
There is no overloaded operator<< allowing printing std::list's content using std::cout.
What you can do?
As #Vlad mentioned, you can write
for ( const God &god : Godmyth )
std::cout << god << '\n';
Alternatively, you can write your own operator<<:
template<typename T>
std::ostream& operator<< (std::ostream &os, const std::list<T> &_list){
os << "[\n";
for ( const auto &item : _list )
os << item << ";\n";
return os << ']';
}

lexical cast from user defined type to int

I am trying to use boost::lexical_cast to convert my user defined type into an integer.
However, I get an exception. What am I missing??
class Employee {
private:
string name;
int empID;
public:
Employee() : name(""), empID(-1)
{ }
friend ostream& operator << (ostream& os, const Employee& e) {
os << e.empID << endl;
return os;
}
/*
operator int() {
return empID;
}*/
};
int main() {
Employee e1("Rajat", 148);
int eIDInteger = boost::lexical_cast<int>(e1); // I am expecting 148 here.
return 0;
}
I know I can always use the conversion operator, but just wondering why lexical cast doesn't work here.
The problem is that what you insert into the output stream is not the representation of an integer (because of the trailing << std::endl). The following fails in a similar way:
boost::lexical_cast<int>("148\n")
Removing the << std::endl makes it work:
friend std::ostream& operator << (std::ostream& os, const Employee& e) {
os << e.empID;
// ^^^^^^^^^^^^^^
// Without << std::endl;
return os;
}

C++ How to iterate through a std::vector of objects and show content on console

For loop should iterate through std::vector and populate content.
First for loop gives me an error message saying:
NO BINARY OPERATOR FOUND << No convert possible
vector<MyClass>classVector;
for (vector<MyClass>::iterator i = classVector.begin();
i != classVector.end();
++i)
{
cout << *i << endl;
}
MyClass.h:
class MyClass{
private:
string newTodayTaskString;
public:
MyClass(string t) : newTodayTaskString (t){}
~MyClass(){}
};
This for loop iterates through a vector of strings and works perfectly. Why?
vector<string>stringVector;
for (vector<string>::iterator i = stringVector.begin();
i != stringVector.end();
++i)
{
cout<<*i<<endl;
}
The question is unrelated to iteration, it's just because you can write
std::string s = "Hello";
std::cout << s;
but not
MyClass o("Hello");
std::cout << o;
See How to properly overload the << operator for an ostream? on how to overload operator << to make it work!
You need to overload the stream operator for your class if you want to be able to directly call std::cout::operator <<.
You can either define it as:
std::ostream& operator << (std::ostream& stream, const MyClass& obj)
{
stream << obj.newTodayTaskString;
}
and declare this operator as friend so it has access to the private members of the class or provide a print function to your class and use that instead.
I think you want to print a member of the class, not the class itself.
For example:
cout << (*i).Name << endl;
you are iterating through the vector of "MyClass", which is perhaps a user-defined type.So you must tell the compiler, in which data of "MyClass" class you are interested in.
Below is a sample code- just for understanding purpose
// Temp_Practice.cpp : Defines the entry point for the console application.
//
#include "stdafx.h"
#include<iostream>
#include<memory>
#include<ostream>
#include <vector>>
using namespace std;
// This example is just for understanding/Demo purpose.
// it will not run on any compiler
class MyClass {
public:
std::string _name;
std::string _address;
int _age;
// Constructor
public:
MyClass() {}
MyClass(std::string name, std::string address, int age) :_name(name), _address(address), _age(age) {}
//Destructor
//..
// other stuff
friend ostream& operator << (ostream& os, std::string _input);
};
ostream& operator << (ostream& os, std::string _input)
{
os << _input.c_str();
return os;
}
int main()
{
std::vector<MyClass> vecMyClass;
MyClass temp("AA", "BB", 1);
vecMyClass.push_back(temp);
MyClass temp1("CC", "DD", 2);
vecMyClass.push_back(temp1);
MyClass temp2("EE", "FF", 3);
vecMyClass.push_back(temp2);
MyClass temp3("GG", "HH", 4);
vecMyClass.push_back(temp3);
MyClass temp4("II", "JJ", 5);
vecMyClass.push_back(temp4);
MyClass temp5("KK", "LL", 6);
vecMyClass.push_back(temp5);
std::vector<MyClass>::iterator itr;
for ( itr = vecMyClass.begin(); itr != vecMyClass.end(); ++itr)
{
// Compiler throws error; it does not know what programer wants to print. So its
// programer responsiblity to let compiler know what to be printed
//std::cout << itr << std::endl; // Error!!!!
// Correct Code
std::cout << itr->_name << itr->_address << itr->_age << std::endl;
}
return 0;
}
You should overload output operator.
#include <iostream>
#include <string>
#include <vector>
#include <iterator>
class MyClass{
private:
std::string newTodayTaskString;
public:
explicit MyClass(const std::string t) : newTodayTaskString (t){}
std::ostream& print(std::ostream& os) const { return os << newTodayTaskString; }
~MyClass(){}
};
std::ostream& operator << (std::ostream& os, const MyClass& obj)
{
return obj.print(os);
}
int main()
{
std::vector<MyClass> vec = {MyClass("add"), MyClass("clear")};
std::copy(vec.begin(), vec.end(), std::ostream_iterator<MyClass>(std::cout, "\n"));
}

C++ output operator overload

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)