Hey ya'll I'm new to vectors and I have created a class of PaintJobContracts, which should have fields for a customer's name, job number, and amount owed. I went ahead and created my class with no issues, but I got stuck in my main file when I tried to create a function that is supposed to prompt the user for info and store it into the vector after validation.
This is the error I am receiving "error: no matching function for call to ‘std::vector::push_back(std::string&)", when I try to do this:
1 2 3 4 5 6 7 8 9 10 11 12 13
//this is a function from my main file. I have a switch(for the user to select a menu choice)
// and I'm calling this function when the user selects the menu choice
void addCustomer(vector<PainterJobContracts> contract)
{
string userInput;
//prompt user to enter name
cout<<"enter you first and last name"<<endl;
//read in name
getline(cin,userInput);
contract.push_back(userInput);
}
Please correct me if I'm wrong, but am I getting this error because the vector expects an object and not a string? If this is the case, how can I get what I've prompted the user to enter to be stored as an object attribute in the vector?
> cout<<"enter you first and last name"<<endl;
...
> which should have fields for a customer's name, job number, and amount owed.
So are you going to input the rest of the information?
At some point, you need to make a new object instance as you surmised.
1 2 3
// just guessing what you need to construct this with
PainterJobContracts newjc(name,jobNo,owed);
contract.push_back(newjc);
> void addCustomer(vector<PainterJobContracts> contract)
This is a copy of your vector, so any changes you make will be lost when the function returns.
So you need to make it a reference. void addCustomer(vector<PainterJobContracts> &contract)
yes, I will be entering the info. In main, I created a vector of PainterJobContracts and when I select addCustomer, I should be prompted to enter the info required, which should then be stored in the vector. I hope that makes sense.
I did this a couple weeks ago using arrays, I would just prompt the user and use my setters to set the user input to the array.
Something like this:
arr[objInArr].setCustomerName(userInput);
PainterJobContracts plain[42]; // has 42 default constructed PainterJobContracts elements
vector<PainterJobContracts> empty; // has array of 0 elements
vector<PainterJobContracts> other(42); // has array of 42 default constructed PainterJobContracts elements
PainterJobContracts con; // default constructed PainterJobContracts
empty.push_back( con ); // copy constructs PainterJobContracts element
// more familiar copy construction: PainterJobContracts tract( con ); ?
// if you can construct a PainterJobContracts from string,
// i.e. there is PainterJobContracts( const string& );
// then:
string words( "Hello world" );
PainterJobContracts sample( words ); // calls PainterJobContracts( const string& );
// and also:
empty.emplace_back( words ); // calls PainterJobContracts( const string& );
Functions take parameters by value or by reference. Parameters are essentially local variables of the function that are initialized in the function call.
1 2 3 4 5 6 7
void sample( PainterJobContracts one, PainterJobContracts& two );
PainterJobContracts input;
sample( input, input );
// function call essentially does:
PainterJobContracts one = input; // copy construction
PainterJobContracts& two = input; // create reference
A plain array is passed by value, but with a huge twist. Function does not get an array. The array is not copied at all.
1 2 3
void addCustomer( PainterJobContracts contract[] );
// is same as
void addCustomer( PainterJobContracts* contract );
Function does not get copy of array. Function gets pointer to array.
1 2 3 4 5 6
PainterJobContracts plain[42];
addCustomer( plain );
// is effectively same as:
PainterJobContracts plain[42];
PainterJobContracts* temporary = plain; // implicit conversion from array to pointer
addCustomer( temporary );
The vector is an object. It has copy constructor that copies values of the array that the vector has.
Therefore, by value vector parameter is a whole, deep copy of callers vector.
By reference is cheap; no copy. By reference allows accessing caller's vector, just like the pointer allows accessing caller's array.
You can have const reference. Then function cannot modify the caller's variable.
void addCustomer(vector<PainterJobContracts>& contract) // <--- Changed.
{
string userInput;
// <--- Other variables you may need.
//prompt user to enter name
cout << "Enter you first and last name: "; // <--- Changed.
//read in name
getline(cin, userInput);
// <--- Other information needed.
contract.emplace_back(userInput, other variables, if needed); // <--- Changed.
}
First like a "std::string" pass the vector by reference.
Inside the function create local variable (s) for what you need for input.
On line 14 use "emplace_back(): not "push_back()".
Putting the local variables inside the ()s will 1st call the overloaded ctor of the class and construct a temporary object object of the class before it finishes with a "push_back" to the vector.
If you are just getting the name create an overloaded ctor that just takes a "std::string" for the name. The compiler will know which overloaded ctor to use based on the parameters, (quantity and type) being the difference.
Without seeing the class I am not sure what else to tell you for now.