Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Doesn't compiler give an ambiguous error for "const" and "not-const" functions

I have overloaded const and non-const functions in c++ structure. Then, I have run the program and I wondered, it's working fine without ambiguous error.

#include <iostream>

struct St 
{
  int f() const 
  { 
      return 1; 
  }

  int f()
  { 
      return 2;
  }
} s;

int main() 
{
    int ret = s.f();  
    std::cout<<ret<<std::endl;
    return 0;
}

So, I just want to know, Why doesn't the compiler give an ambiguous error for "const" and "not-const" functions?

like image 580
msc Avatar asked Oct 05 '17 06:10

msc


People also ask

Can a non-const function call a const function?

const member functions may be invoked for const and non-const objects. non-const member functions can only be invoked for non-const objects. If a non-const member function is invoked on a const object, it is a compiler error.

What will happen if a const object calls a non-const member function?

Since we can't call non-const member functions on const objects, this will cause a compile error.

Can a non member function be const?

No, only a non-static member function may be const qualified. What semantic would you expect from a const non-member function ? If you want to enforce that no parameters are modified by the function, just take them by const reference.


2 Answers

This is const overloading, which is a thing in C++.

In this case, the compiler determines the struct does NOT have an overloaded function return type, (which is disallowed due to ambiguity of course) but rather an overloaded function with different “constness;” a term in one of the other answers which makes sense here.

As for getting no compiler errors:

  1. const overloading is part of the C++ specification, so no errors
  2. At compile-time, the compiler “sees” that the struct is returning to a non-const environment, so uses the non-const function, causing a normal operation to happen

Hope that helps!

like image 160
NonCreature0714 Avatar answered Sep 22 '22 02:09

NonCreature0714


First an informal explanation

Let's take it in logical steps.

A non-const method is allowed and assumed to change the object. As such it can be called on non-const objects only.

A const method is not allowed to change the object. As such it can be called on const objects, but also on non-const objects.

When both overloads of a functions are defined (const and non-const) the method chosen is the one whose constness fits the object constness.

The standard

In reality overload resolution has no special rule for const and non-const methods. Instead, the standard specifies an implicit object parameter. After you take into consideration this implicit object parameter, you can apply the usual overload resolution rules:

§13.3.1 Candidate functions and argument lists [over.match.funcs]

  1. [...] a member function is considered to have an extra parameter, called the implicit object parameter , which represents the object for which the member function has been called. For the purposes of overload resolution, both static and non-static member functions have an implicit object parameter, but constructors do not.

  2. Similarly, when appropriate, the context can construct an argument list that contains an implied object argument to denote the object to be operated on. Since arguments and parameters are associated by position within their respective lists, the convention is that the implicit object parameter, if present, is always the first parameter and the implied object argument, if present, is always the first argument.

  3. For non-static member functions, the type of the implicit object parameter is

    • (4.1) “lvalue reference to cv X” for functions declared without a ref-qualifier or with the & ref-qualifier
    • (4.2) “rvalue reference to cv X” for functions declared with the && ref-qualifier

where X is the class of which the function is a member and cv is the cv-qualification on the member function declaration. [ Example: for a const member function of class X, the extra parameter is assumed to have type “reference to const X”. —end example ] For conversion functions, the function is considered to be a member of the class of the implied object argument for the purpose of defining the type of the implicit object parameter. For non-conversion functions introduced by a using-declaration into a derived class, the function is considered to be a member of the derived class for the purpose of defining the type of the implicit object parameter. [...]

  1. During overload resolution, the implied object argument is indistinguishable from other arguments
like image 20
bolov Avatar answered Sep 22 '22 02:09

bolov