1

Here's a fairly short .cpp program that defines a simple class, implements its == operator, creates a list from the CList template, and adds some instances to the list. The program shows the == operator works as expected and that the list appears to work as expected: List members can be added and retrieved.

But when attempting to call the CList Find() function, the compiler complains:

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

I'm guessing the "left-hand operand" in the error message refers to the this-> in the == operator. If that's the case, I don't see how to fix the problem. If not, can anyone please point out the error in the code?

#include "stdafx.h"
#include <stdint.h>

///////////////////////////////////////////////
// Define a class with a constructor, two
// data members, and a == operator
//

class COpFunc
{
public:
  COpFunc();
  COpFunc( uint32_t opAddr, char opFlag );
  uint32_t addr;
  char     allocFlag;

  BOOL operator == ( COpFunc& f2 )
  {
    return ( this->addr == f2.addr ) && ( this->allocFlag == f2.allocFlag );
  }
};

COpFunc::COpFunc( uint32_t opAddr, char opFlag )
{
  addr      = opAddr;
  allocFlag = opFlag;
};

COpFunc::COpFunc()
{
};

///////////////////////////////////////////////
// Define a list of the COpFunc class
//

CList<COpFunc,COpFunc&> ops;




int _tmain(int argc, TCHAR* argv[], TCHAR* envp[])
{
  HMODULE  hModule = ::GetModuleHandle(NULL);
  POSITION pos;
  COpFunc  temp;

  if (!AfxWinInit(hModule, NULL, ::GetCommandLine(), 0))
    return 1;

///////////////////////////////////////////////
// Create two instances of COpFunc
//

  COpFunc t1( 0x1000, 'a' );
  COpFunc t2( 0x1000, 'a' );

///////////////////////////////////////////////
// Test the == operator
//

  if( t1 == t2 )
    TRACE( "Test 1\n" );      // yep...

  t1.addr = 0x2000;

  if( t1 == t2 )              // nope...
    TRACE( "Test 2\n" );

///////////////////////////////////////////////
// Add the instances to the list
//

  ops.AddTail( t1 );
  ops.AddTail( t2 );

///////////////////////////////////////////////
// Dump the list
//

  pos = ops.GetHeadPosition();

  while( NULL != pos )
  {
    temp = ops.GetNext( pos );
    TRACE( "func: %08x %c\n", temp.addr, temp.allocFlag );
  }

///////////////////////////////////////////////
// Farkle
//

//  pos = ops.Find( t1 );

    return 0;
}
Andrew Truckle
  • 17,769
  • 16
  • 66
  • 164
Fred W
  • 49
  • 2
  • Try changing the signature to `BOOL operator == ( COpFunc const & f2 ) const` – Richard Critten Sep 30 '22 at 19:52
  • You cannot call a nonconst member function on a const object. Dupe: [Why use a const member function?](https://stackoverflow.com/questions/40137928/why-use-a-const-member-function) – Jason Oct 01 '22 at 06:02
  • @JasonLiam The duplicate only address *part* of the issue. Marking the member function `const` won't make the code compile, as explained in [my answer](https://stackoverflow.com/a/73916139/1889329). – IInspectable Oct 01 '22 at 07:41
  • @IInspectable Ok then you should also state the reason in your answer why `f2` should be const qualified. Though i still think that it is trivial but maybe not for OP. Which is why OP should use a [good c++ book](https://stackoverflow.com/questions/388242/the-definitive-c-book-guide-and-list). – Jason Oct 01 '22 at 07:51
  • It amazes me why people insist in using these old-school MFC collections for new code, which even Microsoft who authored them unrecommends. New code should always be built with the Standard C++ library collections; `std::list`, `std::vector`... and so on. There is absolutely no advantage in the old collections and you make your life more difficult for using search functions, and even more when you need to port your code to non Windows/Intel platforms. – sergiol Oct 11 '22 at 16:03

1 Answers1

3

The error message

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

complains about not finding an equality operator that can be applied to a const value. The left-hand operand is the implied this pointer, if the operator is implemented as a class member; this points to a non-const value, unless the member function is const-qualified.

Adding a const qualifier to operator== isn't sufficient, though. It's also required that the right-hand operand (the argument f2) is const-qualified. The correct implementation should thus be:

struct COpFunc
{
    // ...

    bool operator==(COpFunc const& f2) const
    {
        return ( this->addr == f2.addr ) && ( this->allocFlag == f2.allocFlag );
    }
};
IInspectable
  • 46,945
  • 8
  • 85
  • 181