bpgeck bpgeck - 1 year ago 182
C++ Question

Cannot assign to non-static data member within const member function

I am attempting to use

as a hash table to store many
and another class
are defined as follows:

class CreditCard {
string cardHolder;
unsigned long long cardNumber;
int limit;
int balance;

CreditCard(string in_cardHolder, string in_cardNumber, int in_limit) {
cardHolder = in_cardHolder;
cardNumber = stoll(in_cardNumber);
limit = in_limit;
balance = 0;

void ChangeBalance(int amount) const {
balance += amount; // SECOND ERROR

class CardDatabase {
unordered_set<CreditCard> cards;
unordered_set<CreditCard>::iterator iter;

CardDatabase() { }

void AddCard(cardHolder, cardNumber, int limit) {
CreditCard tempCard = CreditCard(cardHolder, cardNumber, limit);

void Charge(string cardHolder, int chargeAmount) {
iter = cards.find(cardHolder);
iter->ChangeBalance(chargeAmount); // FIRST ERROR

Initially I was getting the following compile error at
Member function 'ChangeBalance' not viable: 'this' argument has type 'const CreditCard', but function is not marked const
. So, I added the "const" to the
function. However, after doing that I get the following compile error at
Cannot assign to non-static member within const member function 'ChangeBalance'

Is there any way to fix this error without changing
to a static variable? It is obviously important that the balance be different for each

Any help is appreciated.


Thank you all for your quick answers. I feel I should clarify something. I already added the proper hash functionality elsewhere in my code:

namespace std {
template <>
struct hash<CreditCard> {
size_t operator()(const CreditCard& cc) const
return hash<string>()(cc.GetCardHolder());

Also, the code I posted initially pasted is from a much larger code base and I didn't delete all the necessary namespacing stuff at first before posting the question. My apologies for the confusion.

Answer Source

Members of an unordered_set are constant, and cannot be changed once they're in the unordered_set, by default. You are trying to change the objects in the set, and the compiler is properly telling you that you can't do this.

The only possible way to do this correctly (explained only for educational purposes, because this is bad class design):

  1. Explicitly declare the individual fields that can be modified in this manner as mutable.

  2. Use a custom hash function with your unordered_set, and the hash function must exclude the value of mutable fields from the value of the calculated hash.

Otherwise, modifying the contents of the object in the set obviously changes its hash value, which will result in undefined behavior.

Again, this is explained for informational purposes only. This is not a good class design.

The clean way to do this would be to assign a unique identifier to each CreditCard (you know, like a credit card number?), and use an ordinary std::map, to look up CreditCards by their number.

Recommended from our users: Dynamic Network Monitoring from WhatsUp Gold from IPSwitch. Free Download