You are here:

C++/error C2678(c++)


Dear Mr McArdell

Through search engine online, I found your response for the question about error c2228.  I managed to followed it and appreciated your clear explaination with comprehensive examples.  

With reference online, I have found the fix for the above error using const modifier for a function as follows (without explaination). I  hence would like to understand better about const modifier for function, particularly this case which the error was generated.

I am using c++ MS studio 6.

Task is a struct with member data of type int called prio.

bool operator<(const Task& obj) const{
 return prio<obj.prio;

I thought const modifier for function is optional, at least previously no error was generated in similar case.  My understanding of this modifier is to restrict the changes to object being passed in.  Please clarify.

Thank you for your time.


First let me clarify errors. C2678 is _not_ a C++ error - the C++ standard stipulates where an implementation should determine that code is in error, but does not say what form of reporting errors takes. C2678 is an error specific to your compiler - MSVC++ 6.

Second, you do not say what the error is. I assume it is the same as that documented in an MSDN library I have available:

       "binary 'operator' : no operator defined which takes
        a left-hand operand of type 'type' (or there is no
        acceptable conversion)"

Third, you do not say what piece of code the compiler raised this error for. Was it referring to the < in the operator< you show (prio<obj.prio)? If so then the type of member prio has no operator< defined that can be used for the comparison.
This rather limits the specific help I can give you.

So, to the meaning of const when applied to instance member (and only class/struct instance member) functions; yes it is optional. However if you do not change the state of the object it is a good idea to specify the member function const. Such member functions can then be used by objects of the type that are const. What it actually does is make the this pointer const so that it cannot (easily) be used to modify class instance member data or call non-const instance functions. For a class X the type of the this pointer for an instance member function declared const will be const X * (or X const *). Similar rules apply for instance member functions declared volatile or const volatile.

An instance member function has, in all C++ implementation I know of, a hidden this parameter added by the compiler thus:

     class X { InstanceFn(); }; --> class X { InstanceFn(X * this); };

I have shown the minimum to get the point across. In fact the compiler generates a stand alone function whose name is mangled to include all the information required to identify the function as being the specific member function of class X:

     class X { InstanceFn(); }; --> X_InstanceFn(X * this);

I have not bothered with what the compiler generates for the rest of class X as it is not relevant to our discussion. The above example uses a very simple name mangling scheme - real name mangling schemes are more complex - see the material at, section 5.1 for an example.

Now let us consider an instance member function declared const. The transformation can be considered thus:

     class X { ConstInstanceFn() const; };
         --> X_ConstInstanceFn(const X * this);

Note that in this case the compiler makes the type of the this pointer const X *.

As far as making a call to an instance member function goes:

    X x;
    x.InstanceFn()       -->     X_InstanceFn( &x );

Note that here the instance context (x) is maintained by having &x passed into the function as the this pointer. Now consider a similar example:

    const X x;
    x.InstanceFn()       -->     X_InstanceFn( &x );

This is identical to the previous example except that x is now const. The effect is an error as X_InstanceFn takes a pointer to a non-const X as its this parameter. This is because the declaration of InstanceFn in the class X definition did not specify that it was a const member function.

However, if we call ConstInstanceFn instead then we get no error:

    X x;
    x.ConstInstanceFn()       -->     X_ConstInstanceFn( &x );


    const X x;
    x.ConstInstanceFn()       -->     X_ConstInstanceFn( &x );

In this case as ConstInstFunction was declared to be a const member function the this parameter of the generated X_ConstInstanceFn will be const X * and so can called with values that are X * or const X *.

Note that the above example code snippets are for example and understanding the points being made only. I have not tried compiling them so sorry for any typos.  


All Answers

Answers by Expert:

Ask Experts


Ralph McArdell


I am a software developer with more than 15 years C++ experience and over 25 years experience developing a wide variety of applications for Windows NT/2000/XP, UNIX, Linux and other platforms. I can help with basic to advanced C++, C (although I do not write just-C much if at all these days so maybe ask in the C section about purely C matters), software development and many platform specific and system development problems.


My career started in the mid 1980s working as a batch process operator for the now defunct Inner London Education Authority, working on Prime mini computers. I then moved into the role of Programmer / Analyst, also on the Primes, then into technical support and finally into the micro computing section, using a variety of 16 and 8 bit machines. Following the demise of the ILEA I worked for a small company, now gone, called Hodos. I worked on a part task train simulator using C and the Intel DVI (Digital Video Interactive) - the hardware based predecessor to Indeo. Other projects included a CGI based train simulator (different goals to the first), and various other projects in C and Visual Basic (er, version 1 that is). When Hodos went into receivership I went freelance and finally managed to start working in C++. I initially had contracts working on train simulators (surprise) and multimedia - I worked on many of the Dorling Kindersley CD-ROM titles and wrote the screensaver games for the Wallace and Gromit Cracking Animator CD. My more recent contracts have been more traditionally IT based, working predominately in C++ on MS Windows NT, 2000. XP, Linux and UN*X. These projects have had wide ranging additional skill sets including system analysis and design, databases and SQL in various guises, C#, client server and remoting, cross porting applications between platforms and various client development processes. I have an interest in the development of the C++ core language and libraries and try to keep up with at least some of the papers on the ISO C++ Standard Committee site at


©2017 All rights reserved.