C ++ auto на int16_t приводит к целому числу - PullRequest
19 голосов
/ 12 апреля 2019

Я довольно новичок в C ++ 17 и пытаюсь понять ключевое слово decltype и его сочетание с auto.

Ниже приведен фрагмент кода, который дает неожиданный результат.

#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;
}

Удивительно, но компилятор говорит мне, что есть несоответствие в clamp и что low и high равны int.Если я поменяю auto на int16_t, то в мире все будет хорошо, и все типы будут int16_t, как и ожидалось.

Я задаю вопрос: почему auto бросаетlow и hi до int, когда все типы int16_t? Это хороший вариант использования для decltype?

Даже после прочтения cppreference.com, я неЯ не совсем понимаю, как работает decltype, так что извините за мое невежество.

Ответы [ 2 ]

20 голосов
/ 12 апреля 2019

Проблема не с auto здесь. Когда вы вычитаете два int16_t значения, результатом будет int. Мы можем продемонстрировать это с помощью этого кода здесь :

#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 и b - оба short int s, но когда вы добавляете или вычитаете их, получается обычный int. Это необходимо для предотвращения переполнения /, а также для обратной совместимости.

5 голосов
/ 12 апреля 2019

Это явление называется обычными арифметическими преобразованиями .Он определен в стандартах C и C ++ и (грубо говоря) преобразует все, что меньше int, в int.Он также конвертирует большие типы.Потратьте некоторое время и прочитайте об этом, он вам понадобится довольно часто.

...