String error when expanding a dynamic array - c++

I'm having a problem with trying to append an extra element to a dynamic array. I know I can use vectors, but for academic purposes, I have to use arrays.
#include <iostream>
using namespace std;
template <class T>
class MyList
{
protected:
T* elems;
int itsSize;
public:
MyList(int itsSize):itsSize(itsSize)
{
elems = new T[itsSize];
}
~MyList()
{
delete [] elems;
}
int getSize()
{
return itsSize;
}
virtual void addElem(){}
virtual void getElem(){}
};
template <class T>
class MyStack : public MyList<T>
{
int counter;
public:
MyStack(int size):MyList<T>::MyList(size){counter=0;}
void addElem()
{
T* tmp = new T[counter+1];
for (int i = 0; i<counter+1; i++)
tmp[i] = MyList<T>::elems[i];
counter++;
delete [] MyList<T>::elems;
MyList<T>::elems = tmp;
cin >> MyList<T>::elems[counter-1];
if(cin.fail())
{
cin.clear();
string line;
getline(cin, line);
throw "Wrong String Input--> will enter 0";
}
}
void getElem()
{
for(int i=counter-1; i>=0; i--)
{
cout << "Element-->" << MyList<T>::elems[i] << endl;
}
}
};
int main()
{
int storeChoice;
cout << "Would you like to store integers, strings or rectangles (1,2, or 3)?" << endl;
cin >> storeChoice;
if(storeChoice==1)
{
MyStack<int> numList(1);
cout << "Enter num:";
numList.addElem();
bool choiceAddLoop = true;
while(choiceAddLoop == true)
{
try
{
char choiceAdd;
cout << "Would you like to enter another elem?(y/n)" << endl;
cin >> choiceAdd;
if(choiceAdd=='y')
{
try
{
cout << "Enter num:";
numList.addElem();
}
catch(const char* wrongInput)
{
cout << wrongInput << endl;
}
}
else if(choiceAdd=='n')
{
choiceAddLoop=false;
break;
}
else
throw "Invalid Input.";
}
catch(const char* invalidChoice)
{
cout << invalidChoice;
}
}
cout << endl << "All Elements" << endl;
numList.getElem();
}
else if(storeChoice==2)
{
MyStack<string> stringList(1);
cout << "Enter string:";
stringList.addElem();
bool choiceAddLoop = true;
while(choiceAddLoop == true)
{
try
{
char choiceAdd;
cout << "Would you like to enter another elem?(y/n)" << endl;
cin >> choiceAdd;
if(choiceAdd=='y')
{
cout << "Enter string:";
stringList.addElem();
}
else if(choiceAdd=='n')
{
choiceAddLoop=false;
break;
}
else
throw "Invalid Input.";
}
catch(const char* invalidChoice)
{
cout << invalidChoice;
}
}
cout << endl << "All Elements" << endl;
stringList.getElem();
}
}
When I select the first choice ( integer ) the code will work:
Would you like to store integers, strings or rectangles (1,2, or 3)?
1
Enter num:22
Would you like to enter another elem?(y/n)
y
Enter num:3
Would you like to enter another elem?(y/n)
n
All Elements
Element-->3
Element-->22
Process returned 0 (0x0) execution time : 5.162 s
Press any key to continue.
A problem occurs in the second choice (string):
Would you like to store integers, strings or rectangles (1,2, or 3)?
2
Enter string:hello
Would you like to enter another elem?(y/n)
y
Enter string:terminate called after throwing an instance of 'std::length_error'
what(): basic_string::_M_create
Process returned 3 (0x3) execution time : 6.761 s
Press any key to continue.
It's the same code for both, why does it work only with integers?

The error happens when you call MyStack<T>::addElem(). When you copy the elements from the old array to the new array your loop should stop at counter, not counter+1. Correct version:
for (int i = 0; i<counter; i++)
tmp[i] = MyList<T>::elems[i];
Accessing MyList<T>::elems[counter], which is out of bounds, results in undefined behavior. For the int-case you were just lucky that the data currently stored there could be correctly interpreted as integer, with std::string you had less luck. So the random data which you wanted to interpret as std::string caused the error you got.
Live demo

Related

How to connect sections of an array or organize an array the same as another?

I am not sure how to connect a part of an array or if it is even possible.
My code is as follows:
#include <algorithm>
#include <iostream>
using namespace std;
int main()
{
string name;
string date[3];
double height[3];
double enter;
cout << "Enter name of a pole vaulter: ";
cin >> name;
cout << "Enter date of first vault: ";
cin >> date[0];
cout << "Enter height of first vault: ";
cin >> enter;
if (enter >= 2.0)
{
if (enter <= 5.0)
{
height[0] = enter;
}
else
{
cout << "Incorrect Value";
abort();
}
}
else
{
cout << "Incorrect Value";
abort();
}
cout << "Enter date of second vault: ";
cin >> date[1];
cout << "Enter height of second vault: ";
cin >> enter;
if (enter >= 2.0)
{
if (enter <= 5.0)
{
height[1] = enter;
}
else
{
cout << "Incorrect Value";
abort();
}
}
else
{
cout << "Incorrect Value";
abort();
}
cout << "Enter date of third vault: ";
cin >> date[2];
cout << "Enter height of third vault: ";
cin >> enter;
if (enter >= 2.0)
{
if (enter <= 5.0)
{
height[2] = enter;
}
else
{
cout << "Incorrect Value";
abort();
}
}
else
{
cout << "Incorrect Value";
abort();
}
int len = sizeof(height) / sizeof(height[0]);
sort(height, height + len, greater<int>());
cout << "Stats for " << name << ":" << endl;
for (int i = 0; i < len; i++) {
cout << height[i] << " ";
}
cout << height[0];
}
I am trying to enter dates and a double value, and then organize the double values in descending order and keep the dates with the corresponding value. I am not sure if this is possible, any alternative way of completing this would be helpful.
Thank you
Group of data, data sorting, multiple data points that should be aligned/connected to their respective other data points. I think the best solution here would be the use of a struct or class with vectors:
Let's say you want a variable that contains both your date and number. We can construct a class or structure for that:
#include <iostream>
using namespace std;
struct str1
{
string date;
double number;
};
class cls1
{
public:
string date;
double number;
};
int main()
{
str1 ob1;
cls1 ob2;
ob1.date = "somedate";
ob1.number = 12345;
cin >> ob1.date;
cout << ob1.date << " " << ob1.number << endl;
ob2.date = "somedate2";
ob2.number = 54321;
cin >> ob2.number;
cout << ob2.date << " " << ob2.number << endl;
return 0;
}
Having a class or struct enables you to use objects (variables made from those structs or classes). Every object created has their own place in memory for storing both date and number. You can use, find, search any of these variables and have access to both values this way.
Grouping them up so there's a list of them can be done in vectors.
Vectors are like better arrays. They not only have a dynamical size (meaning its size can change and doesnt stay static like in arrays), but they also have quite a bit ready made functions for you to use:
bool sortingFunction(int &a, int &b)
{
if (a > b) return true;
else return false;
}
int main2()
{
vector<int> numbers;
//to add
numbers.emplace_back(5); //5 is the number to add
//to remove
numbers.erase(numbers.begin() + 2); //2 is the index of the variable to delete
//to sort
sort(numbers.begin(), numbers.end(), sortingFunction);
return 0;
}
Vectors need the #include <vector> header.
Sort is a function that sorts. Needs #include <algorithm> header.
Sort function is neat because you can define the logic behind how you want to sort the vector or array with a seperate function that returns either true or false.
For your example you could do something like this in the end:
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;
struct myType
{
string date;
double number;
};
bool sortByDate(myType &a, myType &b)
{
if (a.date > b.date) return true;
else return false;
}
bool sortByNumber(myType &a, myType &b)
{
if (a.number > b.number) return true;
else return false;
}
int main()
{
vector<myType> variables;
int num;
cout << "how many do you want to add" << endl;
cin >> num;
for(int i = 0; i < num; i++)
{
myType tmp;
cout << "Enter date of var" << i+1 << ": ";
cin >> tmp.date;
cout << "Enter number of var" << i+1 << ": ";
cin >> tmp.number;
variables.emplace_back(tmp);
}
//after that you can use the vector as you want...
//sort
sort(variables.begin(), variables.end(), sortByDate);
sort(variables.begin(), variables.end(), sortByNumber);
//delete
variables.erase(variables.begin()+5);
//or clear the entire thing
variables.clear();
//Either way each item in the vector consists of both number and date thus even
//if you sort the vector the values are still connected at the same position
return 0;
}

C++ SimpleVector Using Templates

I am trying to get my program to let the user choose which data type they would like to use, 1 for int, 2 for double, and 3 for string. Take that type and make it the type for our dynamic array. Allow the user to say how many inputs of the data they would like, and then allow the user to enter the data.
For some reason not clear to me, my program crashes right after the user enters any number for the type they want to use.
(I also have some other methods to implement, but I wanted to get this fixed first. So that's why there are unused methods.)
Is there something I am not seeing here? Any help is greatly appreciated. Thank you so much.
#include <iostream>
#include <cstdlib>
using namespace std;
template <class T>
class SimpleVector
{
private:
T *tempPointer;
int lengthOfArray;
public:
SimpleVector();
~SimpleVector();
SimpleVector(int lengthOfArray);
SimpleVector(const SimpleVector& copy);
int getArraySize();
T getElementAt(int n);
T & operator[](int index);
};
// default no-arg constructor
template <class T>
SimpleVector<T>::SimpleVector()
{
tempPointer = NULL;
lengthOfArray = 0;
}
// destructor for deallocating memory
template <class T>
SimpleVector<T>::~SimpleVector()
{
delete [] tempPointer;
}
// single argument constructor
template <class T>
SimpleVector<T>::SimpleVector(int dynamicArray)
{
lengthOfArray = dynamicArray;
tempPointer = new T[lengthOfArray];
}
// Copy constructor
template <class T>
SimpleVector<T>::SimpleVector(const SimpleVector& copy)
: lengthOfArray(copy.lengthOfArray), tempPointer(new int[copy.lengthOfArray])
{
int newSize = copy->size();
tempPointer = new T[newSize];
for(int i = 0; i < newSize; i++){
tempPointer[i] = copy.tempPointer[i];
}
}
// gets the size of the dynamic array
template <class T>
int SimpleVector<T>::getArraySize()
{
return lengthOfArray;
}
// returns element from array at specified position
template <class T>
T SimpleVector<T>::getElementAt(int n)
{
return *(tempPointer + n);
}
// returns reference to the element in array indexed by subscript
template <class T>
T & SimpleVector<T>::operator[](int index)
{
return this->tempPointer[index];
}
int main()
{
int dataType;
int dataSize = 0;
char keepGoing;
do{
cout << "What type of data do you want to enter?\n(1 for integer, 2 for double and 3 for strings)" << endl;
cin >> dataType;
cout << "How many data inputs? " << endl;
cin >> dataSize;
SimpleVector <int> list1(dataSize);
if (dataType == 1) {
SimpleVector <int> list1(dataSize);
}
else if (dataType == 2) {
SimpleVector <double> list1(dataSize);
}
else if (dataType == 3) {
SimpleVector <string> list1(dataSize);
}
else {
cout << " That's not an available option. Bye! " << endl;
return 0;
}
cout << "Please enter the data:" << endl;
for (int i = 0; i <= dataSize; i++) {
cin >> list1[i];
}
cout << "Do you want to enter data again? (y/n?)" << endl;
cin >> keepGoing;
}while((keepGoing == 'Y') | (keepGoing == 'y'));
return 0;
}
For some reason not clear to me, my program crashes right after the user enters any number for the type they want to use.
I would suggest, that you test your program multiple times, when you are writing it. As #Jarod42 said in his comment, your if statements don't really do much, because your
SimpleVector <type> list1(dataSize);
gets destroyed after { }.
So basically whatever number user types, your SimpleVector will always be of the type int.
Now when you try to:
cout << "Please enter the data:" << endl;
for (int i = 0; i <= dataSize; i++) {
cin >> list1[i];
}
you are calling function:
template <class T>
T & SimpleVector<T>::operator[](int index)
{
return this->tempPointer[index];
}
At this point, you pointer is pointing to NULL, but you are trying to access [index] of your pointer, which is pointing to NULL. That's why you program crashes.
EDIT:
I'm not sure if this is what you want, but i'll give it a try :
do{
cout << "What type of data do you want to enter?\n(1 for integer, 2 for double and 3 for strings)" << endl;
cin >> dataType;
cout << "How many data inputs? " << endl;
cin >> dataSize;
if (dataType == 1) {
SimpleVector <int> list1(dataSize);
cout << "Please enter the data:" << endl;
for (int i = 0; i <= dataSize; i++) {
cin >> list1[i];
}
}
else if (dataType == 2) {
SimpleVector <double> list1(dataSize);
cout << "Please enter the data:" << endl;
for (int i = 0; i <= dataSize; i++) {
cin >> list1[i];
}
}
else if (dataType == 3) {
SimpleVector <string> list1(dataSize);
cout << "Please enter the data:" << endl;
for (int i = 0; i <= dataSize; i++) {
cin >> list1[i];
}
}
else {
cout << " That's not an available option. Bye! " << endl;
return 0;
}
cout << "Do you want to enter data again? (y/n?)" << endl;
cin >> keepGoing;
}while((keepGoing == 'Y') | (keepGoing == 'y'));

I keep getting the error "The variable 'b' is being used without being initialized, and I'm not sure how to fix it

//Benjamin McKinney
//CSCI 2010-10
//Spring 2015
//PASS 3
//Programmed on Windows 8.1 using Visual C++ 2010 Express
//This program plays the game MasterMind
#include <iostream>
#include <iomanip>
#include <string>
#include <fstream>
using namespace std;
struct Player
{
string Name;
int HighScores[6];
bool CheatOn;
};
struct Board
{
int NumHoles;
int Holes[6];
};
struct Guess
{
int Count;
int NumHoles;
int Holes;
};
void printHighScores(string);
void readHighScore(string);
void updateHighScore(string, int);
string getPlayer();
int getBoard();
void playGame(string);
void menu(string);
int main()
{
Player p;
srand((unsigned int)time(0));
cout << "!!! Benjamin McKinney's Master-MasterMind!!!\n";
cout << "--------------------------------------------\n";
getPlayer();
menu(p.Name);
cout << "Goodbye, " << p.Name << endl;
printHighScores(p.Name);
cout << "----------------------------------------------\n";
cout << "!!! Benjamin McKinney's Master-MasterMind!!!\n";
system("PAUSE");
return 0;
}
void printHighScores(string name)
{
return;
}
void readHighScore(string)
{
return;
}
void updateHighScore(string, int)
{
return;
}
string getPlayer()
{
Player p;
cout << "What is your name?\n";
cin >> p.Name;
cout << "Welcome, " << p.Name << endl;
p.CheatOn = false;
readHighScore(p.Name);
return p.Name;
}
int getBoard()
{
Board b;
cout << "Enter the number of holes you would like: ";
cin >> b.NumHoles;
if(b.NumHoles > 6 || b.NumHoles < 1)
{
cout << "Error! You must pick a number between 1 and 6! Try again!\n";
}
for(int i=0;i<b.NumHoles;i++)
{
b.Holes[i] = rand() % 2 + 1;
}
return b.NumHoles;
}
void playGame(string)
{
Player p;
Board b;
Guess g;
getBoard();
g.Count=0;
for(int i=0;i<b.NumHoles;i++)
{
cout << "Enter your guess for the row\n";
if(p.CheatOn == true)
{
for(int a=0;a<(sizeof(b.Holes)-1);a++)
{
cout << b.Holes[a];
}
}
cout << "Enter your guess for hole " << i << ": ";
cin >> g.Holes;
g.Count++;
}
return;
}
void menu(string)
{
Player p;
char choice;
cout << "Please choose an option below:\n";
cout << "\t P)lay\n\t Q)uit\n\tChoice: ";
cin >> choice;
if(choice == 'P')
playGame(p.Name);
else
if(choice == 'Q')
return;
else`enter code here`
if(choice == 'C')
{
p.CheatOn = true;
playGame(p.Name);
}
}
Ignore the three HighScore functions, but otherwise I can't get this to work... "Run-Time Check Failure #3 - The variable 'b' is being used without being initialized." is the main issue that I'm having. If anyone can help me I would really appreciate it. Thanks!
In the playGame function:
void playGame(string)
{
Player p;
Board b; // <----- uninitialized
// ...
for(int i=0;i<b.NumHoles;i++)
// ^^^^^^^^^^
you use b.NumHoles when you have never initialized b.
I guess you intended that getBoard() would magically have some effect on b but it doesn't. The getBoard function updates a local board but never does anything with it.
To fix this you could change getBoard to return the whole board:
Board getBoard()
{
Board b;
// set up b...
return b;
}
and then inside playGame:
Board b = getBoard();
There's another error just below:
for(int a=0;a<(sizeof(b.Holes)-1);a++)
The sizeof operator gives the size in bytes. You actually want the size in elements, so you need to divide by the element size:
a < (sizeof b.Holes / sizeof b.Holes[0])
I'm not sure what the -1 was meant to be doing either, this would just cause you to not output the last hole.

Infinite loop reading from stdin using cin::fail()

I'm struggling with a vector push_back function.
The goal is to have a function which pushes n number of elements until you decide to stop.
So my idea of a 'stop', is cin.fail().
The faulty function is
void pushbackVector(vector<double> &data)
{
double input;
cin >> input;
for (int i = 0; i < 100; i++)
{
if (cin.fail())
{
cout << "Ending input.\n";
return;
}
else
{
data.push_back(input);
}
}
Problem is that when I attempt to use it, I enter a infinite loop.
I have yet to sort the first vector in ASC order, second in DESC order and concatenate the first and second into the third vector. However I'm confident that I can manage this on my own.
Anyway the whole code....
#include<iostream>
#include<vector>
#include<algorithm>
#include<cctype>
using namespace std;
// function prototypes
void menu();
void printVector(const vector<double> &data);
void pushbackVector(vector<double> &data);
void sortVector (vector<double> &data);
int main()
{
menu();
vector<double> row1;
vector<double> row2;
/* not yet used
vector<double> row3;
*/
int input;
cin >> input;
bool exit = 0;
while (!exit)
{
switch (input)
{
case 1:
pushbackVector(row1);
break;
case 2:
pushbackVector(row2);
break;
case 3:
printVector(row1);
break;
case 4:
printVector(row2);
break;
case 5:
cout << "Printing out the contents of row 1\n";
printVector(row1);
cout << "Printing out the contents of row 2\n";
printVector(row2);
cout << "Printing out the contents of row 3\n";
// printVector(row3);
break;
case 6:
cout << "Exitting\n";
exit = 1;
break;
default:
cout << "Invalid choice\n";
}
}
return 0;
}
void menu()
{
cout << "Choose an option\n";
cout << "1) Enter first vector\n";
cout << "2) Enter second vector\n";
cout << "3) Print out the first vector\n";
cout << "4) Print out the second vector\n";
cout << "5) Print out all three vectoros\n";
cout << "6) Exitting the program\n";
}
void printVector(const vector<double> &data)
{
for(int i = 0; i < data.size(); i++)
{
cout << data[i] << ", ";
}
cout << "\n";
}
void pushbackVector(vector<double> &data)
{
double input;
cin >> input;
for (int i = 0; i < 100; i++)
{
if (cin.fail())
{
cout << "Ending input.\n";
return;
}
else
{
data.push_back(input);
}
}
}
void sortVector (vector<double> &data)
{
cout << "Sorting your vector \n";
sort(data.begin(), data.end());
}
You're only reading once, move the read inside the loop:
void pushbackVector(vector<double> &data)
{
double input;
// cin >> input; --------------
//
for (int i = 0; i < 100; i++) //
{ //
cin >> input; // <---------
if (cin.fail())
{
cout << "Ending input.\n";
return;
}
else
{
data.push_back(input);
}
}
That'll make sure that you actually get input. Now, if you're not going to enter 100 values, you need to somehow notify the stream. That's done by insert "EOF character" in it. Press CTRL+Z on windows or CTRL+D on unix terminals.
When this gets read from the stream, it enters a fail (and eof) state and it'll stay like that unless you clear the error flags by calling cin.clear() when appropriate.
You've made the same mistake also in main. You only read once before the while loop, so input keeps the value you initialy entered and keeps entering the same choice. I think that's the infinite loop you're talking about. To fix it, move the read statement just before the switch.
Hope that helps.
Also, this is how I'd write the function:
double input;
for (int i = 0; (cin >> input) && i < 100; ++i) {
data.push_back(input);
}
cout << "Ending input.\n";
Streams can be used in boolean expression - they convert to the result of !fail() - and such are a convenient and idiomatic way to control a loop.
The infinite loop is cause by the fact that you are reading:
cin >> input;
once and then entering a while loop (in your main) that will keep going forever (unless the input is initially equal to 6).
Change:
cin >> input;
bool exit = 0;
while (!exit)
{
// ...
to:
bool exit = 0;
while (!exit)
{
cin >> input;
// ...
Depending on what your logic is, the same is happening in the pushbackVector function at:
double input;
cin >> input;
for (int i = 0; i < 100; i++)
{
// ...
You might want to change that to:
double input;
for (int i = 0; i < 100; i++)
{
cin >> input;
// ...
Do something like this instead:
void pushbackVector(vector<double> &data)
{
double input;
while (cin >> input) //will return true when there's valid input, otherwise false
{
if (input == -1)
{
cout << "Ending input.\n";
return;
}
else
{
data.push_back(input);
}
}
This will read the input until you enter -1 or enter invalid input.
I think relying on cin.fail() is just not a good idea. The proper way to use fail() is explained in the link. It is not what you may expect.
Putting aside the reading which is misplaced, if you enter something you should not, you need to purge the input.
Add in the block of te first if
cin.clear();
cin.ignore( numeric_limits<streamsize>::max(), '\n' );
I would write the function the following way
void pushbackVector( std::vector<double> &data )
{
cin.clear();
cin.ignore( std::numeric_limits<streamsize>::max(), '\n' );
data.insert( data.end(), std::istream_iterator<double>( std::cin ), std::istream_iterator<double>() );
}
I was done some days before but I forgot to post my answer.
Who knew that I could just say if the cin fails, stop the input but don't end the program, lol.
#include<iostream>
#include<vector>
#include<algorithm> // for sort algorithms
#include<iomanip> // for setprecision
using namespace std;
// function prototypes
void menu();
void printVector(const vector<double> &data);
void pushbackVector(vector<double> &data);
void sortVector (vector<double> &data);
int main()
{
vector<double> row1;
vector<double> row2;
vector<double> row3;
int input;
bool exit = false;
while(!exit)
{
menu();
cin >> input;
switch (input)
{
case 1:
cout << "Entering vector 1\n";
pushbackVector(row1);
sortVector(row1);
cout << "\n";
break;
case 2:
cout << "Entering vector 2\n";
pushbackVector(row2);
sortVector(row2);
reverse(row2.begin(), row2.end());
cout << "\n";
break;
case 3:
cout << "Printing out vector 1\n";
printVector(row1);
cout << "\n";
break;
case 4:
cout << "Printing out vector 2\n";
printVector(row2);
cout << "\n";
break;
case 5:
// reserve enough space for all of row1's and row2's elements
row3.reserve(row1.size() + row2.size());
// insert row1's elements at the end of row3
row3.insert(row3.end(), row1.begin(), row1.end());
// insert row2's elements at the end of row3
row3.insert(row3.end(), row2.begin(), row2.end());
cout << "Printing out the contents of vector 1\n";
printVector(row1);
cout << "Printing out the contents of vector 2\n";
printVector(row2);
cout << "Printing out the contents of vector 3\n";
printVector(row3);
cout << "\n";
break;
case 6:
cout << "Exitting\n";
exit = true;
break;
default:
cout << "Invalid choice\n";
}
}
return 0;
}
void menu()
{
cout << "Choose an option\n";
cout << "1) Enter first vector\n";
cout << "2) Enter second vector\n";
cout << "3) Print out the first vector\n";
cout << "4) Print out the second vector\n";
cout << "5) Print out all three vectoros\n";
cout << "6) Exitting the program\n";
}
void printVector(const vector<double> &data)
{
for(int i = 0; i < data.size(); i++)
{
cout << setprecision(4) << data[i] << " ";
}
cout << "\n";
}
void pushbackVector(vector<double> &data)
{
double input;
int numOfItems;
cout << "How many items you want to add into vector?: ";
cin >> numOfItems;
for (int i = 0; i < numOfItems; i++)
{
cin >> input;
if (cin.fail())
{
cout << "Ending input.\n";
return;
}
else
{
data.push_back(input);
}
}
}
void sortVector(vector<double> &data)
{
cout << "Sorting your vector \n";
sort(data.begin(), data.end());
}

push_back() not working for custom data type (template class)

Apparently push_back() is not working for my custom data class T. On compilation I get the following error:
error: no matching function for call to ‘Vector::push_back(int&)’
Could someone explain to me why that is? Thank you.
#include <std_lib_facilities>
#include <numeric>
#include <vector>
#include <string>
// vector<int> userin;
// int total;
// bool success;
class T
{
public:
void computeSum(vector<T> userin, int sumamount, T& total, bool& success);
void getData(vector<T> userin);
};
template <class T>
void computeSum(vector<T> userin, int sumamount, T& total, bool& success)
{
if (sumamount < userin.size()){
success = true;
int i = 0;
while (i<sumamount){
total = total + userin[i];
++i;
}
} else {
success = false;
cerr << "You can not request to sum up more numbers than there are.\n";
}
}
template <class>
void getData(vector<T> userin)
{
cout << "Please insert the data:\n";
int n;
do{
cin >> n;
userin.push_back(n);
} while (n);
cout << "This vector has " << userin.size() << " numbers.\n";
}
int helper()
{
cout << "Do you want help? ";
string help;
cin >> help;
if (help == "n" || help == "no"){
return 0;
}else{
cout << "Enter your data. Negative numbers will be added as 0. Ctrl-D to finish inputing values.\n";
}
}
int main()
{
helper();
getData(userin);
cout << "How many numbers would you like to sum?";
int sumamount;
cin >> sumamount;
computeSum(userin, sumamount);
if (success = true) {
cout << "The sum is " << total << endl;
} else {
cerr << "Oops, an error has occured.\n";
}
cout << endl;
return 0;
}
Outside some flagrantly offensive issues (e.g. it should be template <class T>, not template<class>), the real problem is that vector expects you to push back objects of type T. It looks like you are reading in with type int and pushing. Try:
template <class>
void getData(vector<T> userin)
{
cout << "Please insert the data:\n";
T n;
do{
cin >> n;
userin.push_back(n);
} while (n);
cout << "This vector has " << userin.size() << " numbers.\n";
}
The problem is this line:
userin.push_back(n);
where n is an int. push_back is expecting something of type T.
I'm also not sure what the point of class T is in this case.