views:

697

answers:

6

Error:
error C2678: binary '==' : no operator found which takes a left-hand operand of type 'const entry' (or there is no acceptable conversion)

The function:

template <class T, int maxSize>
int indexList<T, maxSize>::search(const T& target) const
{
    for (int i = 0; i < maxSize; i++)  
     if (elements[i] == target)   //ERROR???
      return i;       // target found at position i

    // target not found
    return -1;
}

indexList.h
indexList.cpp

Is this suppose to be an overloaded operator? Being a template class I am not sure I understand the error?

Solution- The overload function in the class now declared const:

//Operators
bool entry::operator == (const entry& dE)  const <--
{
    return (name ==dE.name);

}
+6  A: 

The problem refers to the type T that is being used in this instance not having an operator== defined. I would guess from your question that this is a class 'entry'.

It might also be that the 'entry' class does not have the operator== defined correctly to take a const entry& as a parameter.

dominic hamon
Bingo, might be worth explaining the correct definitions though (inline friend function) or there could be some *FUN* linker issues later =D
Ed Woodcock
why does elements have to be const?
Tommy
Because your template method is marked const. That means that the compiler must check that you don't call non-const operations on the internal data of the class (element[i])
David Rodríguez - dribeas
+2  A: 

This is likely "const poisoning", where your use of const in the declaration of your search function will force you to add const versions of all the downstream functions you call.

In a function declared const, the this pointer is considered const, which means that all the members you use through that pointer are considered const as well. If your operator == () for whatever type T you are specializing with doesn't explicitly specify const parameters, you will get this error.

If you can't ensure that all Ts you use will have the proper operator == () calls, I'd remove the const specifiers on the member function templates.

mwigdahl
In the template class the == operator is not defined, does it need to be? What is the best way to remove this const poisoning on this function?
Tommy
the term "const poisoning" is rather misleading. the consts are there to keep you from making mistakes and maintaining you constraints in order. If adding a const in one place means you need to add it in other places it only means you should probably have done so before.
shoosh
I'd just remove the "const" following the declarations in the header. You could create a const-enabled wrapper template for operator == (), but it's likely more trouble than it's worth.
mwigdahl
@shoosh: In a hierarchy built from scratch I totally agree with you. When adding code to an existing hierarchy, though, "const poisoning" is an apt term. Use of const in these cases causes cascading compiler errors that require massive rewrites.
mwigdahl
+1  A: 

The type T you're using as a parameter to this class should have an operator==() since the code you give doesn't contain the instantiation of the template its difficult to know what's wrong.

On a different note, the function definitions of a template should be in the .h file along with the class or else the compiler would not be able to instantiate it properly.

shoosh
have definitions in .h
Tommy
+1  A: 

The equality operator for user-defined types is not defined by default. This doesn't have anything to do with your template class, but rather your struct or class "entry".

Therefore in you'll have to override the equality operator in struct entry or class entry.

Alternatively, if you don't want to force everything that uses that template to define an equality operator, you can modify the template interface to accept a Comparator that does the equality comparison.

Jared Oberhaus
+6  A: 

Start by reading the error text exactly as it is:

binary '==' : no operator found which takes a left-hand operand of type 'const entry'

It means it can't find any == operator that accepts an entry type as its left operand. This code isn't valid:

entry const e;
if (e == foo)

You've showed us the code for your list class, but that's not what the error is about. The error is about a lack of operators for the entry type, whatever that is. Either give the class an operator== function, or declare a standalone operator== function that accepts a const entry& as its first parameter.

struct entry {
  bool operator==(const entry& other) const;
};
// or
bool operator==(const entry& lhs, const entry& rhs);

I think the latter is the preferred style.

Rob Kennedy
Thanks. My class did have the operator overloaded, but the function wasn't declared a const
Tommy
A: 

Sometimes it is quite enough to write

...
    if (target == elements[i])
...
baton