How to print out a 2D vector of objects in C++? - c++

I'm writing a program which includes a 2D vector of objects:
class Obj{
public:
int x;
string y;
};
vector<Obj> a(100);
vector< vector<Obj> > b(10);
I've stored some values of vector a in vector b.
I get an error when I try to print it out like this:
for(int i=0; i<b.size(); i++){
for(int j=0; j<b[i].size(); j++)
cout << b[i][j];
cout << endl;
}
error info:
D:\main.cpp:91: error: no match for 'operator<<' (operand types are 'std::ostream {aka std::basic_ostream}' and '__gnu_cxx::__alloc_traits >::value_type {aka Obj}')
cout << b[i][j];
^

Your problem is not related to vectors, it is related to sending object(s) of some user defined type Obj to the standard output. When you send an object to the output stream using the operator<< as you do with:
cout << b[i][j];
the stream does not know what to do with it as none of the 12 overloads accepts a user defined type Obj. You need to overload the operator<< for your class Obj:
std::ostream& operator<<(std::ostream& os, const Obj& obj) {
os << obj.x << ' ' << obj.y;
return os;
}
or even a vector of Objs:
std::ostream& operator<<(std::ostream& os, const std::vector<Obj>& vec) {
for (auto& el : vec) {
os << el.x << ' ' << el.y << " ";
}
return os;
}
For more info on the subject check out this SO post:
What are the basic rules and idioms for operator overloading?

This has nothing to do with your vectors.
You are trying to print an Obj, but you didn't tell your computer how you would like it to do that.
Either print b[i][j].x and b[i][j].y individually, or overload operator<< for Obj.

There is no cout::operator<< that takes a class Obj as a right hand side. You could define one. Simplest solution is to send x and y to cout separately. But use range-based for-loops!
#include <string>
#include <vector>
#include <iostream>
using namespace std;
class Obj {
public:
int x;
string y;
};
vector<vector<Obj>> b(10);
void store_some_values_in_b() {
for (auto& row : b) {
row.resize(10);
for (auto& val : row) {
val.x = 42; val.y = " (Ans.) ";
}
}
}
int main() {
store_some_values_in_b();
for (auto row: b) {
for (auto val : row) {
cout << val.x << " " << val.y;
}
cout << endl;
}
}

Maybe like below
for(int i=0; i<b.size(); i++){
for(int j=0; j<b[i].size(); j++)
cout << "(" << b[i][j].x << ", " << b[i][j].y << ") ";
cout << endl;
}

Related

C++ Overloading output using vector

o, I am attempting to create an overloaded output operator for a vector. This overloaded output operator is suppose to allow me to print the values in the vector in the form
[Data]^[Index]
so for example if the data at index 3 is 4, it should print 3^4.
However, I can't seem to get it to work correctly. I need it to loop through the entire vector, but I can't seem to detect what I'm doing wrong.
Here is the function within the header.
friend ostream & operator << (ostream &out, const vector<int> &c);
Here is what I have for the function in the source file.
ostream & operator << (ostream &os, const vector<int> &c)
{
for (int i = 0; i < c.size(); i++)
{
os << c.at[i];
os << "^";
os << i;
}
return os;
Finally, here is my main
#include "Polynomial.h"
#include <string>
#include <vector>
#include <utility>
int main()
{
vector<int> poly1(10);
vector<int> poly2(10);
int x;
int y;
int choice;
bool done = true;
std::cout << "What do you wish to do?" << std::endl;
std::cout << "1. Add two polynomials" << std::endl;
std::cout << "2. Multiply two polynomials" << std::endl;
std::cout << "3. Evaluate one polynomial at a given value" << std::endl;
std::cout << "4. Find Coefficent for a given polynomial and given exponent" << std::endl;
std::cout << "5. Find the leading exponent for a given polynomial" << std::endl;
std::cout << "6. Exit "<< std::endl;
std::cin >> choice;
if (choice < 1 || choice > 6)
{
do
{
std::cout << "Invalid entry: please reenter choice" << std::endl;
std::cin >> choice;
} while (choice < 1 || choice > 6);
}
if (choice == 1)
{
std::cout << "Please input the first polynomial in the form of: (non-zero coefficient, exponent) pairs" << std::endl;
do
{
std::cin >> x >> y;
poly1.at(y) = x;
std::cout << "done?" << std::endl;
std::cin >> done;
} while (done == false);
std::cout << poly1 << std::endl;
}
if (choice == 2)
if (choice == 3)
if (choice == 4)
if (choice == 5)
if (choice == 6)
system("pause");
I believe that my issue lies somewhere within my main or within the source file, though I haven't worked with overloaded output operators in a very long time, so I'm not sure exactly what needs to be fixed.
There is no problem with your code except that at is function so you cannot use subscript operator with that,hence correct code for the above problem is :
#include <iostream>
#include <string>
#include <vector>
using namespace std;
ostream & operator << (ostream &os, const vector<int> &c)
{
for (int i = 0; i < c.size(); i++)
{
os << c.at(i);
os << "^";
os << i;
}
return os;
}
int main()
{
std::vector<int> v{1,2,3};
std::cout<<v<<std::endl;
return 0;
}
The problem with your code is somewhere else and it's actually hard to find in the first glimpse.
Here :
os << c.at[i];
std::vector::at is a function and it's the same as std::vector operator [], but it's a function and you can't use it like this. change it to :
os << c.at(i); //or os << c[i];
Two minor things to take care of :
it's better to print some delimiter(like -) when you print each value^index because it's hard to read this way.
in this line for(int i = 0; i < c.size(); i++) to avoid getting '<' : signed/unsigned mismatch warning change it to for(unsigned int i = 0; i < c.size(); i++). std::vector::size returns size_type which is an unsigned integral type.

std::setw for the whole operator<< of user-defined type

We know, that the std::setw() influence only on the next output.
So, what standard practice to align
the whole operator<< of user-defined type in table output:
class A
{
int i, j;
public:
friend ostream& opeartor<<(ostream& out, const A& a) {
return << "Data: [" << i << ", " << j << "]";
}
}
// ...
A[] as;
out << std::left;
for (unsigned i = 0; i < n; ++i)
out << std::setw(4) << i
<< std::setw(20) << as[i] // !!!
<< std::setw(20) << some_strings[i]
<< some_other_classes[i] << std::endl;
out << std::right;
Just add a setw() method to your class:
class A
{
int i, j;
mutable int width = -1;
public:
A& setw(int n) {
this->width = n;
return *this;
}
friend ostream& operator<<(ostream& out, const A& a);
};
And when you print it, if you want to align, simply use it:
int main() {
A as[5];
for (auto & a : as)
cout << a.setw(15) << endl;
}

C++ Cycle through the addresses of an object

Objects (that are not dynamic) are blocks of data in memory.
Is there a way to cycle through and print each item in an object?
I tried doing it with 'this' but I keep getting errors.
#include "stdafx.h"
#include <iostream>
#include "TestProject.h"
using namespace std;
class myclass {
int someint = 10;
double somedouble = 80000;
int somearray[5] = {0, 1, 2, 3, 4};
public:
void somefunction();
};
void myclass::somefunction() {
cout << "\n test \n" << this;
myclass *somepointer;
somepointer = this;
somepointer += 1;
cout << "\n test2 \n" << *somepointer;
//Error: no opperator '<<' matches these operands
}
int main() {
myclass myobject;
myobject.somefunction();
return 0;
}
I'm guessing the error is because the types don't match. But I can't really figure a solution. Is there a dynamic type, or do I have to test the type somehow?
You must add friend global std::ostream operator << to display content of object
#include "stdafx.h"
#include <iostream>
using namespace std;
class myclass {
int someint;
double somedouble;
int somearray[5];
public:
myclass()
{
someint = 10;
somedouble = 80000;
somearray[0] = 0;
somearray[1] = 1;
somearray[2] = 2;
somearray[3] = 3;
somearray[4] = 4;
}
void somefunction();
friend std::ostream& operator << (std::ostream& lhs, const myclass& rhs);
};
std::ostream& operator << (std::ostream& lhs, const myclass& rhs)
{
lhs << "someint: " << rhs.someint << std::endl
<< "somedouble: " << rhs.somedouble << std::endl
<< "somearray: { ";
for (int iIndex = 0; iIndex < 5; iIndex++)
{
if (iIndex == 4)
lhs << rhs.somearray[iIndex] << " }" << std::endl;
else
lhs << rhs.somearray[iIndex] << ", ";
}
return lhs;
}
void myclass::somefunction() {
cout << "\n test \n" << this;
myclass *somepointer;
somepointer = this;
somepointer += 1; // wrong pointer to object with `object + sizeof(object)` address,
// data probably has been corrupted
cout << "\n test2 \n" << *somepointer; // displaying objects content
}
int main() {
myclass myobject;
myobject.somefunction();
return 0;
}
as you want to get to the object member using its pointers shifts I post another program
#include "stdafx.h"
#include <iostream>
using namespace std;
#pragma pack (push, 1) // force data alignment to 1 byte
class myclass {
int someint;
double somedouble;
int somearray[5];
public:
myclass()
{
someint = 10;
somedouble = 80000;
somearray[0] = 0;
somearray[1] = 1;
somearray[2] = 2;
somearray[3] = 3;
somearray[4] = 4;
}
void somefunction();
friend std::ostream& operator << (std::ostream& lhs, const myclass& rhs);
};
#pragma pack (pop) // restore data alignment
std::ostream& operator << (std::ostream& lhs, const myclass& rhs)
{
lhs << "someint: " << rhs.someint << std::endl
<< "somedouble: " << rhs.somedouble << std::endl
<< "somearray: { ";
for (int iIndex = 0; iIndex < 5; iIndex++)
{
if (iIndex == 4)
lhs << rhs.somearray[iIndex] << " }" << std::endl;
else
lhs << rhs.somearray[iIndex] << ", ";
}
return lhs;
}
void myclass::somefunction() {
int* pSomeInt = (int*)this; // get someint address
double *pSomeDouble = (double*)(pSomeInt + 1); // get somedouble address
int* pSomeArray = (int*)(pSomeDouble + 1); // get somearray address
std::cout << "someint: " << *pSomeInt << std::endl
<< "somedouble: " << *pSomeDouble << std::endl
<< "somearray: { ";
for (int iIndex = 0; iIndex < 5; iIndex++)
{
if (iIndex == 4)
std::cout << pSomeArray[iIndex] << " }" << std::endl;
else
std::cout << pSomeArray[iIndex] << ", ";
}
}
int main() {
myclass myobject;
myobject.somefunction();
return 0;
}
C++, by design, has no reflection feature. This means there is no generic, type-independent way to acces type metadata (e.g. the list of members if a class and their types) at runtime. So what you're trying to do (if I understand it correctly) cannot be done in C++.
Also I'm not sure what you meant by "objects (that are not dynamic)". all objects are blocks of data in memory, regardless of whether they are dynamically allocated or not.

How to get value from map by key

How I can get value from map by key? I have a vector of ints A, and I have a map. I want to print M[1], but I don't understand how I can do it, because I've got an error:
error: invalid operands to binary expression ('ostream' (aka 'basic_ostream<char>') and 'mapped_type' (aka 'std::__1::pair<int, int>'))
cout << M[1];
~~~~ ^ ~~~~
My code:
int main() {
vector<int> A;
map<int, pair<int,int> > M;
FOR(i,1,maxN) {
pair<int,int> p;
p.first = 1;
p.second = 2;
M[i] = p;
}
FOR(i,0,t) {
int x = A[i];
cout << M[x] << endl;
}
return 0;
}
Value type of the map is a std::pair. You need to individually print the 2 values in the pair:
cout<< M[x].first << "," << M[x].second << endl;
Paani has a good answer. I thought I would post mine, which is the same idea but slightly different.
Instead of printing the values from the pair you can create an ostream function to print any pair.
Like this:
#include <iostream>
#include <utility>
template<class T, class U>
std::ostream& operator<<(std::ostream &os, const std::pair<T, U> &p) {
os << '{' << p.first << ',' << p.second << '}';
return os;
}
int main() {
std::pair<int, int> p(7, 11);
std::pair<std::string, double> q("My Double", 37.02);
std::cout << p << std::endl;
std::cout << q << std::endl;
return 0;
}

error: no type named 'vector' in namespace 'std'

Why this is happening?
error: no type named 'vector' in namespace 'std'; did you mean 'hecto'?
void askForVector(std::vector * vector);
#include <iostream>
#include <vector>
void askForVector(std::vector * vector);
int main()
{
std::vector<int> vector;
int size;
askForVector(&vector);
std::cout << "\nsize: " << vector.size() << std::endl;
std::cout << vector.at(0);
}
void askForVector(std::vector * vector)
{
int size;
std::cout << "please insert the size of vector to order: ";
std::cin >> size;
vector->resize(size);
for(int i = 0; i<size; i++){
std::cout << "please insert a value for the " << i+1 << " position: " ;
std::cin >> vector[i];
}
for(int j: *vector)
std::cout << ":"<<j;
std::cout << ":\n";
}
vector is a template, not a type. Either specify a particular specialisation:
void askForVector(std::vector<int> * vector);
or make the function generic
template <typename T>
void askForVector(std::vector<T> * vector);
You might be better off using a reference rather than a pointer:
void askForVector(std::vector<int> & vector);
or returning the vector by value:
std::vector<int> askForVector() {
std::vector<int> vector;
// your code here
return vector;
}
to avoid errors like
std::cin >> vector[i]; // should be (*vector)[i]
There are multiple issues:
vector is a template, not a type, you need the template argument list e.g. vector<int> in the function signature
Since you're passing a pointer to a vector you need to dereference it before using the subscript operator
std::cin >> vector[i]; // wrong
std::cin >> (*vector)[i]; // correct
The following could work:
#include <iostream>
#include <vector>
void askForVector(std::vector<int> * vector);
int main()
{
std::vector<int> vector;
int size;
askForVector(&vector);
std::cout << "\nsize: " << vector.size() << std::endl;
std::cout << vector.at(0);
}
void askForVector(std::vector<int> * vector)
{
int size;
std::cout << "please insert the size of vector to order: ";
std::cin >> size;
vector->resize(size);
for (int i = 0; i<size; i++){
std::cout << "please insert a value for the " << i + 1 << " position: ";
std::cin >> (*vector)[i];
}
for (int j : *vector)
std::cout << ":" << j;
std::cout << ":\n";
}
Example