Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

When do I get "overloaded definition needed" error?

Take this simple example:

#include <iostream>

using namespace std;

void Display(char a, char b, char c)
{
   cout << a << " " << b << " " << c << endl;
}

int main()
{
   Display(2, 3, 4); // Why no syntax error?
   Display(2.0, 3.0, 4.0); // Also no error? O.o
   Display('a', 'b', 'c');
 
   system("pause");
   return 0;
}

I was expecting errors on the first two Display() calls, that would say:

No definition for Display() that takes (int, int, int) found.

No definition for Display() that takes (double, double, double) found.

Where then I would have to overload Display() and add ones that accept the proper parameters.

So in what cases do I actually get the syntax error? And why I did not get the error in this case?

like image 845
Sandra K Avatar asked Dec 09 '25 09:12

Sandra K


1 Answers

This is just how C++ works. The compiler will try to implicitly convert the type you give it to the type it needs, even if it is a narrowing conversion (an exception was made if doing brace initialization. There you get an error). In this case it will convert the int that you give it into a char with the same value an continue on.

Since all of the values you provided are compile time constants in the range of [0, 127], this can never fail so you won't even get a warning that you could be overflowing.

If you had used something like

Display(2000, 32, 47);

You would get warning from GCC and Clang like

GCC
main.cpp:12:12: warning: overflow in conversion from 'int' to 'char' changes value from '2000' to ''\37777777720'' [-Woverflow]
    Display(2000, 32, 47);

Clang   
main.cpp:12:12: warning: implicit conversion from 'int' to 'char' changes value from 2000 to -48 [-Wconstant-conversion]
    Display(2000, 32, 47);

Letting you know you're doing something bad, but it can only do so if it knows what the values are. If you have

int main()
{
    int a, b, c;
    std::cin >> a >> b >> c;
    Display(a, b, c);
    Display('a', 'b', 'c');

    return 0;
}

Then it doesn't know what the values are so it won't issue a warning.

If you really want to stop this you can add an overload that takes ints and delete it so it will cause a compiler error like

void Display(char a, char b, char c)
{
   cout << a << " " << b << " " << c << endl;
}

void Display(int, int, int) = delete;

int main()
{
    int a, b, c;
    std::cin >> a >> b >> c;
    Display(a, b, c);
    return 0;
}

Error:

prog.cc: In function 'int main()':
prog.cc:31:20: error: use of deleted function 'void Display(int, int, int)'
     Display(a, b, c);
                    ^
prog.cc:25:6: note: declared here
 void Display(int, int, int) = delete;

You can also go all out and use

template<typename T, typename U, typename V>
void Display(T, U, V) = delete;

and this will make calling Display an error with anything other than 3 chars.

like image 123
NathanOliver Avatar answered Dec 10 '25 22:12

NathanOliver