0

I currently have a Person class, and have created a PersonList class that extends List, specifically for objects of type Person. When I instantiate a new PersonList I get one error that stops the entire build from happening successfully:

error C2678: binary '==' : no operator found which takes a left-hand operand of type 'Person' (or there is no acceptable conversion) c:\program files\microsoft visual studio 11.0\vc\include\xutility 3186 1 ConsoleApplication3

Here is the PersonList class:

#pragma once
#include<iostream>
#include<sstream>
#include<string>
#include<algorithm>
#include "linearList.h"
#include "myExceptions.h"
#include "changeLength1D.h"
#include <Person.h>

using namespace std;

template<class Person>
class PersonList: public linearList<Person> 
{
public:
PersonList(int initialCapacity = 10);
PersonList(const PersonList<Person>&);
~PersonList() {delete [] element;}

bool empty() const {return listSize == 0;}
  int size() const {return listSize;}
  Person& get(int theIndex) const;
  int indexOf(const Person& theElement) const;
  void erase(int theIndex);
  void insert(int theIndex, const Person& theElement);
  void output(ostream& out) const;

  // additional method
  int capacity() const {return arrayLength;}

  protected:
  void checkIndex(int theIndex) const;
        // throw illegalIndex if theIndex invalid
  Person* element;            // 1D array to hold list elements
  int arrayLength;       // capacity of the 1D array
  int listSize;          // number of elements in list
  };

template<class Person>
PersonList<Person>::PersonList(int initialCapacity)
{// Constructor.
if (initialCapacity < 1)
{ostringstream s;
  s << "Initial capacity = " << initialCapacity << " Must be > 0";
 throw illegalParameterValue(s.str());
}
arrayLength = initialCapacity;
element = new Person[arrayLength];
listSize = 0;
 }

template<class Person>
PersonList<Person>::PersonList(const PersonList<Person>& theList)
{// Copy constructor.
arrayLength = theList.arrayLength;
listSize = theList.listSize;
element = new Person[arrayLength];
copy(theList.element, theList.element + listSize, element);
}


template<class Person>
void PersonList<Person>::checkIndex(int theIndex) const
{// Verify that theIndex is between 0 and listSize - 1.
if (theIndex < 0 || theIndex >= listSize)
{ostringstream s;
s << "index = " << theIndex << " size = " << listSize;
throw illegalIndex(s.str());
}

}

template<class Person>
Person& PersonList<Person>::get(int theIndex) const
{// Return element whose index is theIndex.
 // Throw illegalIndex exception if no such element.
 checkIndex(theIndex);
 return element[theIndex];
 }   

 template<class Person>
int PersonList<Person>::indexOf(const Person& theElement) const
{// Return index of first occurrence of theElement.
 //  Return -1 if theElement not in list.

  // search for theElement
  int theIndex = (int) (find(element, element + listSize, theElement)
                     - element);

   // check if theElement was found
  if (theIndex == listSize)
   // not found
    return -1;
    else return theIndex;
    }

template<class Person>
void PersonList<Person>::erase(int theIndex)
{// Delete the element whose index is theIndex.
 // Throw illegalIndex exception if no such element.
 checkIndex(theIndex);

 // valid index, shift elements with higher index
 copy(element + theIndex + 1, element + listSize,
                            element + theIndex);

   element[--listSize].~Person(); // invoke destructor
  }



template<class Person>
void PersonList<Person>::insert(int theIndex, const Person& theElement)
{// Insert theElement so that its index is theIndex.
if (theIndex < 0 || theIndex > listSize)
{// invalid index
  ostringstream s;
  s << "index = " << theIndex << " size = " << listSize;
  throw illegalIndex(s.str());
}

// valid index, make sure we have space
 if (listSize == arrayLength)
  {// no space, double capacity
     changeLength1D(element, arrayLength, 2 * arrayLength);
     arrayLength *= 2;
  }

  // shift elements right one position
   copy_backward(element + theIndex, element + listSize,
             element + listSize + 1);

    element[theIndex] = theElement;

     listSize++;
    }

template<class Person>
void PersonList<Person>::output(ostream& out) const
{// Put the list into the stream out.
 copy(element, element + listSize, ostream_iterator<Person>(cout, "  "));
 }

// overload <<
template <class Person>
ostream& operator<<(ostream& out, const PersonList<Person>& x)
 {x.output(out); return out;}

The Person Class:

#pragma once
#include <string>

using namespace std;


class Person
{
public:
Person(string firstName, string lastName, string birthday, string hometown);
Person(void);
~Person(void);
string name;
string birthday;
string hometown;
};

The same thing happens in an arrayList class I tried using earlier. Is there a way to get it so I can simply store person objects in an ArrayList type structure?

7
  • 1
    Is operator== implemented for the Person class? Commented Feb 1, 2013 at 19:11
  • No, How exactly do you implement an operator? Commented Feb 1, 2013 at 19:13
  • linearList is an abstract class that defines the main methods used in list structures Commented Feb 1, 2013 at 19:15
  • @AlexAlex, just compare those members, that needs to be compared. Commented Feb 1, 2013 at 19:16
  • 1
    @AlexAlex, stackoverflow.com/questions/4421706/operator-overloading Commented Feb 1, 2013 at 19:21

1 Answer 1

1

Your function indexOf() contains a call to STL's std::find() algorithm, which internally performs comparisons between pairs of values to determine if the element passed as a third argument is contained in the range defined by the first two arguments.

To perform this comparison, std::find() uses the == operator. However, no operator == has been defined for objects of type Person.

In order to solve the problem, you must overload the comparison operator == for instances of Person. You can do it, for instance, this way:

class Person
{
    ...
public:
    friend bool operator == (Person const& p1, Person const& p2)
    {
        // Perform the comparison and return "true" if the objects are equal
        return (p1.name == p2.name) && ... 
    }
};
Sign up to request clarification or add additional context in comments.

2 Comments

Ok, that seems to work for the "==". It then brings up the "<<" operator with the same message. Do I have to overload all the operators in order to use arrayList?
@AlexAlex: Yes. That's because you use std::copy and ostream_iterator, which actually result in output insertions. Output insertions use the operator << so, if you want to output an object of type Person you need to overload operator <<. I assume you know how to do it, because I see you've done it for the class template PersonList.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.