c++constantspass-by-referencepass-by-valuepass-by-const-reference

Multiple functions with the same name but their parameters are either constant or received by value or by reference


The title is a bit lengthy, but it's best explained by an example:

Suppose we have the following functions in C++:

void SomeFunction(int num) { //1

}

void SomeFunction(int& num) { //2

}

void SomeFunction(const int& num) { //3

}

void SomeFunction(const int num) { //4

}

All of these are called the same way:

SomeFunction(5);

or

int x = 5;
SomeFunction(x);

When I tried to compile the code, it rightfully says more than one instance of overloaded function "SomeFunction" matches the argument

My question is: Is there a way to tell the compiler which function I meant to call?

I asked my lecturer if it was possible, and she tried something along

SomeFunction< /*some text which I don't remember*/ >(x);

But it didn't work and she asked me to find out and tell her.

I also encounter this post: How to define two functions with the same name and parameters, if one of them has a reference? And it seems that 1 and 2 can't be written together, but what about 3 and 4? Can either one of those be called specifically?


Solution

  • 1 and 4 have the same signature, so you'll need to drop one of those.

    The other functions cannot be called directly, but you could add a template function that allows you to specify the desired parameter type:

    template<class Arg>
    void Call(void f(Arg), Arg arg)
    {
        f(arg);
    }
    
    // Driver Program to test above functions
    int main()
    {
        int i;
        Call<int>(SomeFunction, 1);
        Call<int&>(SomeFunction, i);
        Call<const int&>(SomeFunction, 1);
    }
    

    Alternatively you could use a function pointer to choose the signature.

    int i;
    static_cast<void(*)(int)>(&SomeFunction)(1);
    static_cast<void(*)(int&)>(&SomeFunction)(i);
    static_cast<void(*)(const int&)>(&SomeFunction)(1);
    

    It would be preferrable to avoid this scenario though and only define overloads for either references or the signature void SomeFunction(int).


    Note:

    SomeFunction<some text which I don't remember>(x);
    

    only works for template functions and SomeFunction is not a template function, so this is not an option here.