简体   繁体   中英

C++ auto on int16_t casts to integer

I am pretty new to C++17 and am attempting to understand the decltype keyword and how it pairs with auto .

Below is a snippet of code that produces an unexpected result.

#include <typeinfo>
#include <iostream>
#include <algorithm>

using namespace std;

int main() {

  int16_t mid = 4;
  auto low = mid - static_cast<int16_t>(2);
  auto hi = mid + static_cast<int16_t>(2);

  int16_t val;
  cin >> val;

  val = std::clamp(val,low,hi);

  return 0;
}

Surprisingly, the compiler tells me there is a mismatch in clamp and that low and high are int . If I change auto to int16_t all is good in the world and all the types are int16_t as expected.

The question I'm posing is, why does auto cast low and hi to int when all of the types are int16_t ? Is this a good use case for decltype ?

Even after reading cppreference.com, I don't fully understand how decltype works, so excuse my ignorance.

The problem isn't with auto here. When you subtract two int16_t values, the result is an int . We can demonstrate it with this code here :

#include <iostream>
#include <cstdint>
using namespace std;

template<class T>
void print_type(T) {
    std::cout << __PRETTY_FUNCTION__ << std::endl; 
}

int main() {
    int16_t a = 10;
    int16_t b = 20;
    print_type(a);
    print_type(b);
    print_type(a - b); 
    return 0;
}

a and b are both short int s, but when you add or subtract them it produces a regular int . This is to help prevent overflow / and is also for backwards compatibility.

This phenomenon is called the usual arithmetic conversions . It is defined in the C and C++ standards and (roughly said) converts anything smaller than an int to an int . It converts larger types as well. Take some time and read about it, you'll need it quite often.

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