7

there is a question about overloading functions. Look at this code:

#include<iostream>

void fv(int){}
void fc(const int){}
void fvr(int&){}
void fcr(const int&){}

void fm(void(*fun)(const int))
{
    std::cout << "Constant called" << std::endl;
}

//void fm(void(*fun)(int))
//{
//  std::cout << "non Constant called" << std::endl;
//}

void fm(void(*fun)(const int&))
{
    std::cout << "Constant ref called" << std::endl;
}

void fm(void(*fun)(int&))
{
    std::cout << "non Constant ref called" << std::endl;
}

int main()
{
    fm(&fc);
    fm(&fv);
    fm(&fvr);
    fm(&fcr);
    return 0;
}

if you uncomment void fm(void(*fun)(int)) function you find that compiler can't statically overload function by pointer on function that accept parameter by value and pointer on function that accept const value. Also, if you uncomment void(*fun)(const int) and comment void(*fun)(const int) then all compiles sucessfully. But, if we using references it compiles OK. Don't get why, could you explain me please? Does this mean that pointers to function that accept parameter by value and by const value is same types?

UPD: Top-level const doesn't influence a function signature There is a good explanation why top-level const should be removed.

Community
  • 1
  • 1
brachistochron
  • 321
  • 1
  • 11

2 Answers2

3

Yes, top-level const will be just dropped. Error from gcc

redefinition of ‘void fm(void (*)(int))’

As you can see const is dropped.

Quote from N3376 8.3.5/5

After producing the list of parameter types, any top-level cv-qualifiers modifying a parameter type are deleted when forming the function type.

ForEveR
  • 55,233
  • 2
  • 119
  • 133
  • why it dropped for values and not dropped for references? – brachistochron Mar 19 '15 at 09:11
  • @brachistochron just because const in reference is not top-level const. – ForEveR Mar 19 '15 at 09:21
  • yep, get it, thanks. but still can't get why it works this way =) – brachistochron Mar 19 '15 at 09:24
  • 2
    If you compare function parameters `T*` and `T const*` or `T&` and `T const&`, you will find that it makes a big difference. If you compare `T` and `T const`, there is a difference, too, but is very little and not visible to the caller, hence the standard just says that it doesn't make a different function signature. Similarly, `T*` and `T*const` make little difference. Note that `T&` and `T&const` can't be compared, since the latter simply doesn't exist. – Ulrich Eckhardt Mar 19 '15 at 09:34
2

Yes you cannot overload functions based on the const ness of a non pointer / non-reference argument, see: Functions with const arguments and Overloading

Which in turn implies that pointers to function that accept parameter by value and const value are same type.

Community
  • 1
  • 1
Vikash Balasubramanian
  • 2,921
  • 3
  • 33
  • 74