C++ - Invalid operands to binary expression 'basic_ostream<char>' - c++

I have an 'IntList' class with a dynamic array of integers, but the following fragment of test code gives me troubles:
main.cpp
#include <iostream>
#include "IntList.hpp"
using std::cout;
using std::endl;
int main(int argc, const char * argv[]) {
IntList list{};
cout << "list-1 -> " << list << endl;
return 0;
}
IntList.hpp:
#ifndef IntList_hpp
#define IntList_hpp
#include <stdio.h>
using std::ostream;
class IntList
{
public:
int *dynarray;
int capacity;
int used;
IntList();
void pushBack(int x);
int getCapacity();
void print(ostream& sout);
};
#endif
IntList.cpp
#include <iostream>
#include "IntList.hpp"
using std::cout;
using std::endl;
using std::string;
using std::ostream;
IntList::IntList()
{
int capacity = 1;
int used = 0;
int *dynarray = new int[capacity];
}
ostream& operator<<(ostream& sout, const IntList& list)
{
for (int i = 0; i < list.used; ++i)
sout << list.dynarray[i] << " ";
return sout;
}
From what I understood, I tried to overload the << operator with this:
invalid operands to binary expression ('ostream' (aka 'basic_ostream<char>') and 'ostream')
but I don't know where I get it wrong because XCode gives me this error:
Invalid operands to binary expression ('basic_ostream<char>' and 'IntList')
Any idea how to solve this ?

It appears (from the fragments you have shown) that there is no declaration of your << override in the header file (IntList.hpp). Thus, the code in your main function is not (and cannot be) aware of that override, which is provided in a separate source file.
You need to add a declaration of that override function in the header (tyically, just after the class definition), like this:
// Declaration (prototype) of the function for which the DEFINITION is provided elsewhere
extern ostream& operator<<(ostream& sout, const IntList& list);
Further, your IntList constructor has some serious faults. In it, you are assigning values to three local variables (whose data will be completely lost when the constructor finishes). Those variables are hiding the member variables with the same names. Use this, instead (i.e. remove the int declaration specifiers):
IntList::IntList()
{
// int capacity = 1; // This declares a local variable that hides the member!
capacity = 1;
used = 0;
dynarray = new int[capacity];
}

Related

Structure Arrays & Pointers

I have to use a struct array called Robot_parts[] for each part_rect struct (part_num, part_name, part_quantity, part_cost)
And through the void display function, I have to display Robot_parts[] array entirely through pointer but I don't know how, and I don't know where to declare Robot_parts[] and whether i have to put any number value inside the brackets.
So far I have:
#include <iostream>
#include <string>
using namespace std;
void display();
struct part_rec
{
int part_num;
string part_name;
int part_quantity;
double part_cost;
};
int main()
{
part_rec Robot_parts[ ] = {
{7789, "QTI", 4, 12.95},
{1654, "bolt", 4, 0.34},
{6931, "nut", 4, 0.25}
};
return 0;
}
void display()
{
cout<<Robot_parts[]<<endl<<endl;
}
If I also made a few other errors, please let me know. Thanks!
As stated in a comment it would be much better to use a c++ container like a std::vector or std::array.
But since your professor requires an old-style array, you could try like the code below - see the comments for explanation:
#include <iostream>
#include <string>
#include <vector>
using namespace std;
struct part_rec
{
int part_num;
string part_name;
int part_quantity;
double part_cost;
};
// You have to pass a pointer (to the array) and the size of the array
// to the display function
void display(part_rec* Robot_parts, int n);
// Make a function so that you can "cout" your class directly using <<
// Note: Thanks to #BaumMitAugen who provided this comment and link:
// It makes use of the so called Operator Overloading - see:
// https://stackoverflow.com/questions/4421706/operator-overloading
// The link is also below the code section
std::ostream &operator<<(std::ostream &os, part_rec const &m)
{
// Note - Only two members printed here - just add the rest your self
return os << m.part_num << " " << m.part_name;
}
int main()
{
part_rec Robot_parts[] {
{7789, "QTI", 4, 12.95},
{1654, "bolt", 4, 0.34},
{6931, "nut", 4, 0.25}
};
display(Robot_parts, 3);
return 0;
}
void display(part_rec* Robot_parts, int n)
{
// Loop over all instances of your class in the array
for (int i = 0; i < n; ++i)
{
// Print your class
cout << Robot_parts[i] << endl;
}
}
The link recommended by #BaumMitAugen:
Operator overloading

Instance of class only allows 1 method, or program crashes

I am learning classes and OOP, so I was doing some practice programs, when I came across the weirdest bug ever while programming.
So, I have the following files, beginning by my class "pessoa", located in pessoa.h:
#pragma once
#include <string>
#include <iostream>
using namespace std;
class pessoa {
public:
//constructor (nome do aluno, data de nascimento)
pessoa(string newname="asffaf", unsigned int newdate=1996): name(newname), DataN(newdate){};
void SetName(string a); //set name
void SetBornDate(unsigned int ); //nascimento
string GetName(); //get name
unsigned int GetBornDate();
virtual void Print(){}; // print
private:
string name; //nome
unsigned int DataN; //data de nascimento
};
Whose functions are defined in pessoa.cpp
#include "pessoa.h"
string pessoa::GetName ()
{
return name;
}
void pessoa::SetName(string a)
{
name = a;
}
unsigned int pessoa::GetBornDate()
{
return DataN;
}
void pessoa::SetBornDate(unsigned int n)
{
DataN=n;
}
A function, DoArray, declared in DoArray.h, and defined in the file DoArray.cpp:
pessoa** DoArray(int n)
{
pessoa* p= new pessoa[n];
pessoa** pointer= &p;
return pointer;
}
And the main file:
#include <string>
#include <iostream>
#include "pessoa.h"
#include "DoArray.h"
#include <cstdio>
using namespace std;
int main()
{
//pessoa P[10];
//cout << P[5].GetBornDate();
pessoa** a=DoArray(5);
cerr << endl << a[0][3].GetBornDate() << endl;
cerr << endl << a[0][3].GetName() << endl;
return 0;
}
The weird find is, if I comment one of the methods above, "GetBornDate" or GetName, and run, the non-commented method will run fine and as supposed. However, if both are not commented, then the first will run and the program will crash before the 2nd method.
Sorry for the long post.
Let's look into this function:
int *get()
{
int i = 0;
return &i;
}
what is the problem with it? It is returning pointer to a local variable, which does not exist anymore when function get() terminates ie it returns dangling pointer. Now your code:
pessoa** DoArray(int n)
{
pessoa* p= new pessoa[n];
return &p;
}
do you see the problem?
To clarify even more:
typedef pessoa * pessoa_ptr;
pessoa_ptr* DoArray(int n)
{
pessoa_ptr p= whatever;
return &p;
}
you need to understand that whatever you assign to p does not change lifetime of p itself. Pointer is the same variable as others.

C++ - Confusion over particular example of class instantiation from Professor

My professor gave the following code:
Main.cpp
#include "state.h"
#include <string>
#include <iostream>
using namespace std;
int main(int argc, char const *argv[]){
const int success = 0;
string name;
State x;
State y = "s2"; // This doesn't compile
State z = y;
State* p = new State(z);
x = *p;
p->set_name("s3");
delete p;
x.get_name(name);
std::cout << "Name of state x is " << name << std::endl;
std::cout << "Total number of states is " << State::total_number_of_states() << std::endl;
return success;
}
State.h
#ifndef STATE_H
#define STATE_H
#include <string>
using namespace std;
class State
{
private:
string* name; // str pointer used for illustrative purposes
static int number_of_states;
public:
State();
State(string state_name);
State(const State& state); // Will basically be the copy constructor
virtual ~State();
State& operator=(const State& state); // Copy on equal
void get_name(string& state_name) const;
void set_name(string state_name);
static int total_number_of_states();
};
typedef State *State_pointer;
#endif
In g++ 4.8 on Ubuntu, I get the following error:
$ g++ example_main_1.cpp state.cpp
example_main_1.cpp: In function ‘int main(int, const char**)’:
example_main_1.cpp:14:12: error: conversion from ‘const char [3]’ to non-scalar type ‘State’ requested
State y = "s2"; // This doesn't compile
I asked him about this in class, he said that this is valid C++ and that it should work. I've never seen this kind of class instantiation before, where it would have to convert from a string literal to a std::string then convert that to a State object.
My professor then went on to point out that there are other equivalent invocations that are extremely close:
State y = "s2"; // Does NOT compile
State y("s2"); // Does compile
State y = string("s2"); // Does compile
What's going on here? Why does the first not compile, but the second and third do? As well, is my professor mistaken in saying that the first statement should work? Or is it behavior that's compiler specific?
It looks like your State object has a constructor that takes string. The literal "s2" is type const char [3]. This is why you are receiving the error.
It is also compiler specific. The following code snippet works in VS2013, yet not G++:
struct State
{
State(string s) { }
};
int main() {
State s = "a";
}

C++ Error: Was not declared in the scope

Hey guys I'm working on a project and I was doing pretty well until I hit this wall..
I am getting two errors:
error: 'binarySearch' was not declared in this scope
error: 'addInOrder' was not declared in this scope
Here are my files, I've tried quite a few things with no avail. Help would be much appreciated.
histogram.cpp
#include "histogram.h"
#include "countedLocs.h"
//#include "vectorUtils.h"
#include <string>
#include <vector>
using namespace std;
void histogram (istream& input, ostream& output)
{
// Step 1 - set up the data
vector<CountedLocations> countedLocs;
// Step 2 - read and count the requested locators
string logEntry;
getline (input, logEntry);
while (input)
{
string request = extractTheRequest(logEntry);
if (isAGet(request))
{
string locator = extractLocator(request);
int position = binarySearch (countedLocs,
CountedLocations(locator, 0));
/** Hint - when looking CountedLocations up in any kind
of container, we really don't care if the counts match up
or not, just so long as the URLs are the same. ***/
if (position >= 0)
{
// We found this locator already in the array.
// Increment its count
++countedLocs[position].count;
}
else
{
// This is a new locator. Add it.
CountedLocations newLocation (locator, 1);
addInOrder (countedLocs, newLocation);
}
}
getline (input, logEntry);
}
// Step 3 - write the output report
for (int i = 0; i < countedLocs.size(); ++i)
output << countedLocs[i] << endl;
}
countedLocs.cpp
#include "countedLocs.h"
#include <iostream>
#include <vector>
using namespace std;
int CountedLocations::binarySearch(const vector<CountedLocations> list, CountedLocations searchItem)
{
//Code was here
}
int CountedLocations::addInOrder (std::vector<CountedLocations>& vectr, CountedLocations value)
{
//Code was here
}
countedLocs.h
#ifndef COUNTEDLOCATIONS
#define COUNTEDLOCATIONS
#include <iostream>
#include <string>
#include <vector>
struct CountedLocations
{
std::string url;
int count;
CountedLocations (){
url = "";
count = 0;
}
CountedLocations(std::string a, int b){
url = a;
count = b;
}
int addInOrder (std::vector<CountedLocations>& vectr, CountedLocations value);
int binarySearch (const std::vector<CountedLocations> list, CountedLocations searchItem);
};
inline
std::ostream& operator<< (std::ostream &out, CountedLocations& cL)
{
//out << "URL: " << cL.url << " count: " << cL.count << std::endl;
out << "\"" << cL.url << "\"," << cL.count;
return out;
}
#endif
The methods are member methods of CountedLocations... use something.extractLocator and something.binarySearch or make the histogram() to be also a member method of CountedLocations... (something is of type CountedLocations highly possibly will be countedLocs[position])
You have a free function histogram in which you are trying to use two member functions, addInOrder and binarySearch. In order to use them, you need to have an instance of CountedLocations.
If these are some kind of helper functions, which do not depend on the actual CountedLocations instance, I would turn them into static functions like this (you only need to change the header):
static int addInOrder (std::vector<CountedLocations>& vectr, CountedLocations value);
And then you can call this function by specifying the type of your class:
CountedLocations::addInOrder(...);
You are trying to call member methods of a struct without an object of that type. Strange.
You need to look at what a namespace is.
You declare a class CountedLocations, so far so good. But then you try to use the member functions outside the CountedLocations namespace which will obviously never work.
int position = binarySearch (countedLocs,
CountedLocations(locator, 0));
binarySearch is a member function of the CountedLocations namespace. If you want to call that function you have to create an object that contains a reference to that member function.
CountedLocation myObject;
int position = myObject.binarySearch (countedLocs, CountedLocations(locator, 0));
I dont know if that solves your problem, but you should know this before you even attempt to solve a problem.

A pointer to a bound function may only be used to call the function

I'm working on a homework assignment for my C++ class and have ran across a problem that I cannot figure out what I am doing wrong.
Just to note, the separation of the files is necessary and I realize this would be much easier if I just made a structure AttackStyles inside the main and forgo the additional class file altogether.
The base of my problem is that I cannot seem to be able to loop through an array of classes and pull out base data. Here is the code:
// AttackStyles.h
#ifndef ATTACKSTYLES_H
#define ATTACKSTYLES_H
#include <iostream>
#include <string>
using namespace std;
class AttackStyles
{
private:
int styleId;
string styleName;
public:
// Constructors
AttackStyles(); // default
AttackStyles(int, string);
// Destructor
~AttackStyles();
// Mutators
void setStyleId(int);
void setStyleName(string);
// Accessors
int getStyleId();
string getStyleName();
// Functions
};
#endif
/////////////////////////////////////////////////////////
// AttackStyles.cpp
#include <iostream>
#include <string>
#include "AttackStyles.h"
using namespace std;
// Default Constructor
AttackStyles::AttackStyles()
{}
// Overloaded Constructor
AttackStyles::AttackStyles(int i, string n)
{
setStyleId(i);
setStyleName(n);
}
// Destructor
AttackStyles::~AttackStyles()
{}
// Mutator
void AttackStyles::setStyleId(int i)
{
styleId = i;
}
void AttackStyles::setStyleName(string n)
{
styleName = n;
}
// Accessors
int AttackStyles::getStyleId()
{
return styleId;
}
string AttackStyles::getStyleName()
{
return styleName;
}
//////////////////////////////////////////////
// main.cpp
#include <cstdlib>
#include <iostream>
#include <string>
#include "attackStyles.h"
using namespace std;
int main()
{
const int STYLE_COUNT = 3;
AttackStyles asa[STYLE_COUNT] = {AttackStyles(1, "First"),
AttackStyles(2, "Second"),
AttackStyles(3, "Third")};
// Pointer for the array
AttackStyles *ptrAsa = asa;
for (int i = 0; i <= 2; i++)
{
cout << "Style Id:\t" << ptrAsa->getStyleId << endl;
cout << "Style Name:\t" << ptrAsa->getStyleName << endl;
ptrAsa++;
}
system("PAUSE");
return EXIT_SUCCESS;
}
My question is why do I get the error:
"a pointer to a bound function may only be used to call the function"
on both ptrAsa->getStyleId and ptrAsa->getStyleName?
I cannot figure out what is wrong with this!
You are missing () around the function calls. It should be ptrAsa->getStyleId().
You are missing parenthesis on both calls, it should be
ptrAsa->getStyleId()
to call the function.
ptrAsa->getStyleId
is used to refer to a member value / attribute.
You need to invoke the function, not merely reference it:
std::cout << "Style Id:\t" << ptrAsa->getStyleId() << "\n";
std::cout << "Style Name:\t" << ptrAsa->getStyleName() << "\n";
You are Forgot to put () in last in Your Function(ptrAsa->getStyleId ) Calling with arrow operator.