0

Full Error:

Error 2 error C2678: binary '==' : no operator found which takes a left-hand operand of type 'Item' (or there is no acceptable conversion) c:\program files (x86)\microsoft visual studio 12.0\vc\include\algorithm 1734 1 GameStore


Inventory Class (cpp file)

#include <iostream>
#include <string>
#include <vector>
#include <algorithm>
#include <Windows.h>
#include "item.h"

class Inventory
{


public:

void Inventory::viewInventory()
{
    for (int i = 0; i < inventory.size(); i++)
    {
        Inventory::inventory[i].getItemName();
    }
}

void Inventory::addItem(Item& item)
{
    inventory.push_back(item);
}


void Inventory::removeItem(Item& item)
{
    if (std::find(inventory.begin(), inventory.end(), item) != inventory.end())
    {
        inventory.erase(std::remove(inventory.begin(), inventory.end(), item), inventory.end());
    }

    else
    {
        std::cout << "Item does not exist" << std::endl;
    }
}

//Player Gold methods
int Inventory::getGold()
{
    return playerGold;
}

void Inventory::setGold(int newGold)
{
    playerGold = newGold;
}


int Inventory::addGold(int newGold)
{
    playerGold += newGold;
    return playerGold;
}

int Inventory::removeGold(int newGold)
{
    playerGold -= newGold;
    return playerGold;
}
//Player Gold methods




private:
std::vector<Item> inventory = {};
int playerGold;

};

Basically what I am trying to do is make an inventory system that holds objects from the class "Item". I spent a long time getting my for loops and all of my methods to work, then as the sky has never been more clear I get an error from which is way out out my league.


Item Class (CPP)

#include "item.h"
#include <iostream>
#include <string>


Item::Item(int id, std::string name, std::string description, std::string examime)
{
    itemName = name;
    itemID = id;
    itemDescription = description;
    itemExamine = examime;

}

void Item::setItemName(std::string newName)
{
    itemName = newName;
}

void Item::setItemDescription(std::string newDescription)
{
    itemDescription = newDescription;

}

void Item::setItemExamine(std::string newExamine)
{
    itemExamine = newExamine;
}

void Item::setItemID(int newID)
{
    itemID = newID;
}

std::string Item::getItemName()
{
    return itemName;
}

std::string Item::getItemDescription()
{
    return itemDescription;
}

std::string Item::getItemExamine()
{
    return itemExamine;
}

int Item::getItemID()
{
    return itemID;
}

Item Class (header)

#include <iostream>
#include <string>

class Item
{
public:
    //constructor
    Item::Item(int id, std::string name, std::string description, std::string examime);

    //setters
    void setItemName(std::string newName);
    void Item::setItemDescription(std::string newDescription);
    void Item::setItemExamine(std::string newExamine);
    void Item::setItemID(int newID);

    //getters
    std::string Item::getItemName();
    std::string Item::getItemDescription();
    std::string Item::getItemExamine();
    int Item::getItemID();

private:
    std::string itemName;
    int itemID;
    std::string itemDescription;
    std::string itemExamine;

};

If you have any advice even if it is to redo my whole system of going about this that would be great. The classes are obviously very bare and I am going to add a lot more. Meaning i'm not looking for an answer like "You don't even need an Item class"

Thanks for any help!

  • 1
    That error message seems pretty clear. You don't have an `==` operator which takes a left-hand-side argument of type `Item`. If you want to compare custom types (like your class `Item` is) then you need to *overload* the suitable comparison operators yourself. – Some programmer dude Oct 13 '17 at 06:47
  • 1
    If you don't understand why the compiler complains about the `==` operator, since you don't actually use it anywhere directly, think about what the [`std::find`](http://en.cppreference.com/w/cpp/algorithm/find) function does and how it might work... – Some programmer dude Oct 13 '17 at 06:48
  • This might be useful: https://stackoverflow.com/q/4421706/1025391 – moooeeeep Oct 13 '17 at 06:51
  • Do you *really* need the "setters"? They do little more than circumvent encapsulation. – Bathsheba Oct 13 '17 at 06:55
  • @Bathsheba I'm currently in my first few weeks of programming, and I was taught to make getters and setters for each data member of my class that isn't constant. – Jacob OConnor Oct 13 '17 at 06:59
  • @JacobOConnor: An odd thing to teach indeed. Being able to tweak individual members obviates the need for making them private. Programs are more stable if you only set members in constructors whenever possible. – Bathsheba Oct 13 '17 at 07:01

1 Answers1

3

The "core" problem of your code seems to be the lack of an operator== implementation for your Item class, as the compiler error tells you.

As a C++ beginner (no worries: everyone of us was a beginner), you may very well ask why is this op== required, as you don't call it explicitly in your code. Well, it's true you don't call it explicitly, but the code in the standard library implementation does it. In particular, you invoke std::find (implemented in the<algorithm> header, that is cited in your error message):

void Inventory::removeItem(...)
{
    if (std::find(inventory.begin(), inventory.end(), item) != inventory.end())
    {
        ...

std::find needs to compare Item instances with op==. So, to try to fix your code, please define an operator== for comparing Items, like this:

// In the Item class header:

class Item 
{
   ...
};

inline bool operator==(const Item& a, const Item& b) 
{
    // Implement your comparison logic for Items a and b.
    // ...
    // Return true if "a == b".
}

As additional side notes, when you declare member functions inside your class, you don't need to use the Item:: prefix before the member function:

class Item
{
public:
    //constructor
    Item::Item(int id, std::string name, std::string description, std::string examime);

    //setters
    void setItemName(std::string newName);
    void Item::setItemDescription(std::string newDescription);
    void Item::setItemExamine(std::string newExamine);
    void Item::setItemID(int newID);
    ...

Just do:

class Item
{
public:
    //constructor
    Item(int id, std::string name, std::string description, std::string examime);

    //setters
    void setItemName(std::string newName);
    void setItemDescription(std::string newDescription);
    void setItemExamine(std::string newExamine);
    void setItemID(int newID);

    ...

Moreover, consider making your getters const, to make your class const-correct, e.g.:

   class Item 
   {
     public:
       ... 
       std::string getItemName() const;
       std::string getItemDescription() const;
       std::string getItemExamine() const;
       int getItemID() const;

       ...
   };
Mr.C64
  • 41,637
  • 14
  • 86
  • 162