简体   繁体   中英

C++ Overloading different with signed and unsigned int

When compiling C++ with overloaded function definitions why is the promotion behaviour different between signed and unsigned integer types? Is this expected behaviour?

In the example below, the call to "fail" in main is ambiguous but the call to "pass" is not.

unsigned int fail(unsigned int a) {
  return a;
}

unsigned int fail(unsigned short a) {
  return a;
}

int pass(int a) {
  return a;
}

int pass(short a) {
  return a;
}


int main(){

  unsigned char a;
  char b;
  fail(a);
  pass(b);

  return 0;
}

Sample output (from clang, VS compiler gives something similar):

fail.cpp:22:3: error: call to 'fail' is ambiguous
  fail(a);
  ^~~~
fail.cpp:1:14: note: candidate function
unsigned int fail(unsigned int a) {
             ^
fail.cpp:5:14: note: candidate function
unsigned int fail(unsigned short a) {
             ^
1 error generated.

According to integral promotion (emphasis mine):

The following implicit conversions are classified as integral promotions:

  • signed char [...] can be converted to int ;
  • unsigned char [...] can be converted to int if it can hold its entire value range, and unsigned int otherwise;
  • char can be converted to int or unsigned int depending on the underlying type: signed char or unsigned char (see above);

Note that all other conversions are not promotions; for example, overload resolution chooses char -> int (promotion) over char -> short (conversion).

In your case, given that int is able to hold the entire value range of both signed char and unsigned char , only int pass(int a) is a promotion which is more preferable than the remaining three which are conversions, and there is no preference among the conversions.

Those implicit conversions indeed follow different rules.

  • char -> int is a promotion

  • char -> short is a conversion

and promotion is chosen over conversion because it forbids any precision loss. That's why pass passes.

Whereas

  • unsigned char -> unsigned int is a promotion only if int can't represent the full range of values unsigned char s can; if not, the promotion is unsigned char -> int .

I suspect that, in your case, int can indeed represent all values in the range of unsigned char . This means that fail has a choice between two two-steps conversion paths: unsigned char -> int -> unsigned int and unsigned char -> int -> unsigned short and can't decide between them.

source: http://en.cppreference.com/w/cpp/language/implicit_conversion

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM