3

My question is why automatic type conversion does not work when calling overloaded functions in c++. Example code is below:

void test(char t);
void test(short t);
void test(long long t);

void main(){
    int a=8;
    test(a);
}

If I compile codes above with g++/clang++, an error of function overload ambiguous would occur at

test(a)

Why not the compiler apply automatic type conversion rules here? Variable a in function main() is type of int which should be conversed into type long long to avoid loss of precision. I don't want to write duplicated function for type int or long. Of course I could avoid the error with explicit cast below:

test((long long)a)

However, do I have to use explicit cast every time I need to call test(long long) for parameters of type int or long? Is there any way of making the compiler more smarter?

Thank you for the answers.

2 Answers2

2

In short - yes, you have to cast explicitly each time.

In you case, the problem is that you have more than one possible type conversion. int could be implicitly converted in all three types you have (char, short, long long). So compiler can't determine what type conversion to use in this case.

You could read more about implicit type conversions here http://en.cppreference.com/w/cpp/language/implicit_conversion

You can achieve you goal with templates:

// any type that hasn't explicit definition
template <typename T = long long>
void test(T t);

// process char differently
void test(char c);

// process short differently
void test(short c);

It's surely UNSAFE but possible. I advice you to add static assert inside your template function.

  • Thank you for your answer. I read the link and it says automatic type conversion for numeric conversions is from narrower ones to wider ones to avoid loss of precision, right? In my cases, char and short are narrower than int, so int should not be implicitly converted in them, but int could be implicitly converted in long long because long long is wider than int. It would result in loss of precision when implicitly converting int into char or short. Dose the compiler do think int could be implicitly converted in all three types I have (char, short, long long)? – user3475622 Aug 12 '17 at 04:52
  • Don't sure but as far I know all compilers behave in this way. In my opinion - explicit is better than implicit. – Vlad Sydorenko Aug 12 '17 at 05:56
  • Please see my edited answer if you really need to achieve your goal. – Vlad Sydorenko Aug 12 '17 at 06:15
  • Thank you for your answer. Using template solved my problem. I still hope the compiler or c++ standard could be much more smarter :) – user3475622 Aug 12 '17 at 09:17
2

Any automatic type conversion is an implicit conversion if not done explicitly in the source code.The Values of integral types narrower than int (char, signed char, unsigned char, short int and unsigned short) is promoted to int

so when you do this it get confused which one to call (as both implicitly becomes void test (int t)

void test(char t);
void test(short t);

int main(){
    int a=8;
    test(a);

}

But when you send the exact data type info no confusion

#include<iostream>


void test(int  t);
void test(short t);
void test(long long t);

int main(){
    int a=8;
    test(a);
}

If you will leave on compiler to decide definitely you will be in problem

Follow the link to stop implicit conversion

Stop Implicit conversion

Hariom Singh
  • 3,512
  • 6
  • 28
  • 52
  • I know that automatic type conversion is an implicit conversion, but why does the compiler get confused? char and short is narrower than int, and int is narrower than long long, so if test(a) call test(char) or test(short), a would lose some precision while calling test(long long) is perfect. One of the rules of automatic type conversion for numeric conversions is to avoid loss of precision, right? – user3475622 Aug 12 '17 at 04:44
  • My teacher used to tell a story :) its like when you want to hand a letter to son , if son is not available father can take the letter.In your case since when you do int a=8; test(a); no of the reciever are available so trying so multiple people are behaving like father ..Try something void test(int t); void test(short t); int main(){ int a=8; test(a); } you will see no problem – Hariom Singh Aug 12 '17 at 04:48
  • Its like when you confuse the compiler ..compiler will confuse you .If there is function which accepts int then send int .Don't let compiler to assume – Hariom Singh Aug 12 '17 at 04:49
  • Well, I think it is because the compiler is not smart enough. I just don't want to write duplicated functions such as test(int) or test(long), because they behaves the same as test(long long) while test(char) and test(short) behave differently. I thought the compiler could automatically determine which overloaded function to use but it seems I am wrong. Thank you for your answer. I hope the compiler could be smarter in such cases because it isn't complex to implement, right? – user3475622 Aug 12 '17 at 05:04