0

I am getting a compiler error when I am trying to use the push_back method on my list.

Here is my code:

// Point iterator to the proper warehouse.
set<cs3505::warehouse>::iterator curr_warehouse = warehouses.find(warehouse);

// Insert new inventory_item into the warehouse.

// Create a copy of today's date, and increment it.
cs3505::date exp_date = current_date;
exp_date.increment(curr_food.get_shelf_life());

// Create a new inventory item.
cs3505::inventory_item new_item(curr_food, exp_date);
// Set the quantity of the new item.
new_item.set_quantity(qty);

// Now insert the item.
// Adding new items being at the end ensures the oldest items will be at the 
// beginning of the list.
(*curr_warehouse).inventory.push_back(new_item);

Compiler error:

report.cc:134: error: passing ‘const std::list >’ as ‘this’ argument of ‘void std::list<_Tp, _Alloc>::push_back(const _Tp&) [with _Tp = cs3505::inventory_item, _Alloc = std::allocator]’ discards qualifiers

The last line of my code is line 134. Thanks for any help. I've been banging my head on this for a few hours.

This is the definition for an inventory_item:

/*
 * An inventory item which includes a food item, an expiration date,
 * and quantity.
 */

#include "inventory_item.h"
#include "date.h"
#include "food_item.h"

namespace cs3505
{
// inventory_item definitions

/*
 * Constructs an inventory item.
 */
inventory_item::inventory_item(food_item &item, date &exp_date)
{
    this->item = item;
    this->expiration_date = exp_date;
    this->quantity = 0;
}

/*
 * Destructs a food item.
 */
inventory_item::~inventory_item() { }

/*
 * Returns this inventory item's food item.
 */
food_item inventory_item::get_food_item()
{
    return this->item;
}

/*
 * Returns the expiration date for this inventory item.
 */
date inventory_item::get_exp_date()
{
    return this->expiration_date;
}

/*
 * Returns the quantity of this inventory item.
 */
int inventory_item::get_quantity()
{
    return this->quantity;
}

/*
 * Sets the quantity of this food item.
 */
void inventory_item::set_quantity(int change)
{
    this->quantity = change;
}
}

I also have a custom warehouse class that has a list. I'm trying to add an inventory item to that list.

LuckyPrime
  • 28
  • 1
  • 5

1 Answers1

2

The error here is because you're ignoring a const qualifier. This is because iterators returned by sets must be const. This restriction is in place because all elements in a set must be unique; changing the value of an element in a set through an iterator can break this contract.

I can't find the exact reference offhand (and SGI's reference for std::set doesn't mention this), so instead I'll link through to another Stackoverflow post the explains this: C++ STL set update is tedious: I can't change an element in place

EDIT: Found it.

std::set is a type of Simple Associative Container, meaning the values are the same as the keys. The following paragraph then sums this up:

The types X::iterator and X::const_iterator must be the same type. That is, a Simple Associative Container does not provide mutable iterators.

This does mean that my first paragraph is technically slightly wrong. It is not to ensure that you do not change a set's elements to the same value from underneath it, rather, is it simply by design. It is actually a side effect of the "keys are immutable" invariant on the base Associative Container concept.

Despite this, I'm going to leave it up there to not make this a major edit.

Community
  • 1
  • 1
slugonamission
  • 9,562
  • 1
  • 34
  • 41