Help with nonstandard syntax

I keep on getting the error non-stand syntax; use '&' to create a pointer to member for the if (itemName == itemsToPurchase.at[&i]) and allItemsCount.at[&index] = itemQuantity;. I included the & by the i's because I was trying to get it to work. And I also keep on getting the error binary '==' no operator found which takes left operand of type 'std::string'(or there is no acceptable conversion) for the line itemName == itemsToPurchase.at[&i]). Please I need help debugging, and I want to understand what I'm doing wrong. I am at my wits end trying to get this to work.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
//Here is the shopping cart class
class ShoppingCart {
private:
	string custName;
	string custDate;
	vector<ItemToPurchase*> itemsToPurchase;
	vector<int*> allItemsCount;
	int itemQuantity;
	const int NOT_FOUND = -1;
public:
	ShoppingCart();
	void CustName(string name);
	void CartDate(string description);
	void AddItem(string itemName, string itemDescription, double itemPrice, int itemQuantity);
	void RemoveItem(string itemName);
	void UpdateQuantity(string itemName, int itemQuantity, int newQuantity);
	void PrintDescriptions(string itemName);
	void PrintTotal();
	int FindItem(string itemName);
	int LocateItem(string itemName);
	double GetCostCart();
	string GetCustName();
	string GetCartDate();
	string AddItem();
	string GetRemoveItem();
	int GetQuantity();
};

//here is the itemtoPurchase class
class ItemToPurchase {
private:
	string itemName;
	string itemDescription;
	double itemPrice;
	int itemQuantity;
	string itemAdd;
public:
	ItemToPurchase();
	ItemToPurchase(string name, string description, double price, int quantity);
	void SetName(string name);
	void SetDescription(string description);
	void SetPrice(double price);
	void SetQuantity(int quantity);
	void PrintItemCost();
	//void PrintItemCost();
	string GetName();
	string GetDescription();
	double GetPrice();
	int GetQuantity();
};


// locate item function  
int ShoppingCart::LocateItem(string itemName)
{
	int index = NOT_FOUND;  // assume item is not found to begin
	for (int i = 0; i < itemsToPurchase.size(); i++)
	{
		//if (itemName == itemsToPurchase[i])   // finding the objects
		if (itemName == itemsToPurchase.at[&i])
			index = i;
	}
	return index;
}
// update item function
void ShoppingCart::UpdateQuantity(string itemName, int itemQuantity, int newQuantity) {
	int index = 0;
	//string newQuantity = " ";
	index = LocateItem(itemName);
	
	cout << "Enter the item name:" << endl;
	getline(cin, itemName);
	cout << "Enter the new quantity:" << endl;
	cin >> newQuantity;
	if (index == NOT_FOUND) {
		cout << "Item not found in cart." << endl;
	}
	else {
		allItemsCount.at[&index] = itemQuantity;
		cout << "Updated quantity of " << itemName << "to " << itemQuantity << endl;
	}
}
1
2
3
4
5
vector<ItemToPurchase*> itemsToPurchase;
string itemName;
int i;

itemName == itemsToPurchase.at[ &i ]

This is delicious.

The itemsToPurchase is a std::vector.
Its element-type is ItemToPurchase*.

Lets say you get syntax right and get one element.
You will then compare std::string against ItemToPurchase*.
How are you supposed to compare a string and a pointer?


Lets say you get syntax right ... what have you there?
The std::vector does have a member function at.
How does one call a function? With parentheses (). Not with brackets [].
Reread how to access an element of a vector.

The i is an integer. Integer is ok as an index of an element in vector.
Address of integer is effectively a pointer. A pointer is not ok as index.


What do you actually want to compare?
I want the itemName to compare what's inside of the itemtoPurchase vector, and if the itemName matches something within the vector, then I want it to return that itemName into the following function.
I also have used the parentheses method, and it still keeps on giving me the error
Error (active) E0513 a value of type "int" cannot be assigned to an entity of type "int *"
for the allItemsCount.at(index) = itemQuantity; and if (itemName == itemsToPurchase.at(i)) . Please can somebody walk me through this?? I really am just trying to understand. I don't want the answer given to me. I just want to understand.
Hello!

TLDR
Figuring out how to access values of objects stored in vectors can be tricky for new programmers. In this case, the solution is to use the arrow operator -> to call the GetName() function.
/TLDR

1) First, let's look at how the ItemToPurchase class currently works.

Each ItemToPurchase object holds data about the item, including the item name which is a string. You already have a GetName() function so let's use it. Example:

1
2
3
4
5
// create an Apple object and a pointer to access it
ItemToPurchase * apple = new ItemToPurchase("Green Apple", "A sour green apple", 0.99, 1);

// access the apple's name using the arrow operator
cout << apple->GetName() << endl;


You may wonder why we're using the arrow -> operator to access GetName(). That's because the "apple" object we created is a pointer rather than the object itself. This mirrors your ShoppingCart class which stores a vector of pointers.

2) Now we know how to call GetName() to retrieve the item's name by itself. The next step is to use it in a vector of ItemToPurchase pointers.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
// vector holds items added to shopping cart
vector<ItemToPurchase*> allItemsToPurchase;   

// create example objects (ShoppingCart::AddItem() function should do something similar)
ItemToPurchase * apple = new ItemToPurchase("Green Apple", "A sour green apple", 0.99, 1);
ItemToPurchase * orange = new ItemToPurchase("Orange", "It's just an orange", 1.25, 1);

// ...and add them to the vector
allItemsToPurchase.push_back(apple);
allItemsToPurchase.push_back(orange);

// Setup complete. Let's print the name of each item in vector
for (int i = 0; i < allItemsToPurchaset.size(); i++)
{
	cout << allItemsToPurchase[i]->GetName() << endl;
}


The important part is allItemsToPurchase[i]->GetName(). You can read this in English as: Look in our vector at the current index and get the pointer there. It points to the object we want. Then use the arrow operator to access the object's GetName() method.

What does it return? A string. Why does it return a string? Because we said it does in the ItemToPurchase class. Why is that useful? Because now we can compare the itemName with the string in the LocateItem() function:

1
2
3
4
5
for (int i = 0; i < itemsToPurchase.size(); i++)
{
    if (itemName == itemsToPurchase[i]->GetName())
	index = i;
}


Please do not add this code directly in to your project. The goal is not to give you the code, but to walk through a simple example to solve of the problem you're having. Considering the level of knowledge your code demonstrates, you should be able to understand every step of the example. If something is unclear, feel free to ask and we can clarify.

P.S.
Does it have to be that way? No, it doesn't. I personally avoid pointers unless the project explicitly requires it. How can we do it differently? By using a vector of objects instead of a vector of pointers. This lets you use the dot operator rather than the arrow operator:

vector<ItemToPurchase> rather than vector <ItemToPurchase*>.

P.P.S.
I mentioned it in your other thread, and I'm going to repeat it here. Don't ask for user input inside ShoppingCart::UpdateQuantity(). You already know what you're looking for thanks to the "string itemName" argument.
Last edited on
Thank you for your help. I need clarification on one point though. So does the pushback add to the vector? Right now I am trying to pushback apart of the code and it says the vector subscript is out of range.
Last edited on
Yes. push_back() is a common way to add an element to the end of the vector.
http://www.cplusplus.com/reference/vector/vector/push_back/

Since push_back() always adds to the end of the vector, you don't specify a location.

It's easy to use because the vector always knows where it's last element is. It's also fast because it doesn't need to reorganize other elements in the array. A downside is that it may leave your vector unsorted depending on the order you add elements.
Last edited on
It's also fast because it doesn't need to reorganize other elements in the array.

In that sense, yes.

However, vector stores elements in an array. It preallocates an array of some size and then stores values into that array. IF you have to store (push) more than preallocated amount, the vector has to allocate larger array and move existing elements into the new array before storing the new value. That is a fully-automatic process.

One can use http://www.cplusplus.com/reference/vector/vector/reserve/ to minimize reallocations (if one knows final size of the vector).
the reallocation algorithm is decent these days, but if you keep growing the container, the reallocs will destroy performance for sure. For similar reasons, insert() and other operations on the front or middle of a vector are costly.

you can also use (size) to pre-allocate:
vector <int> fixedsize(1000);

Last edited on
you can also use (size) to pre-allocate:
vector <int> fixedsize(1000);

That is different.

You did create a vector that has 1000 integers.

You could do that like this too:
1
2
3
4
5
6
vector<Bar> foo;
foo.resize(1000);
// foo has 1000 Bars
Bar gaz;
foo.push_back( gaz ); // likely to cause a realloc
// foo has 1001 Bars 


Reserve is something else:
1
2
3
4
5
6
vector<int> foo;
foo.reserve(1000);
// foo has 0 Bars
Bar gaz;
foo.push_back( gaz ); // no realloc
// foo has 1 Bar 

Reserve changes capacity, not size.
this is probably redundant as many others have pointed this out but the line of code that is giving you errors is

1
2
3

if (itemName == itemsToPurchase.at[&i])


itemsToPurchase is a vector of pointers to type ItemsToPurchase so you cannot access it with . now if this was java which just deals with references this would be possible but that's another language (maybe you also use java) anyway to access a pointers data members you need to use the special syntax -> which is shortcut for (*itemsToPurchase.at(i)).GetName()) but it would be clearer to say ItemsToPurchase.at(i)->getName()

hope that helps

note I added .getName() to distinquish the items
Topic archived. No new replies allowed.