Функция, возвращающая удвоение, когда ожидается долгое
Недавно я ответил на другой вопрос, и в моем ответе был следующий код.
template<typename T, typename ... Ts>
struct are_arithmetic{
enum {
value = std::is_arithmetic<T>::value && are_arithmetic<Ts...>::value
};
};
template<typename T>
struct are_arithmetic<T>{
enum {
value = std::is_arithmetic<T>::value
};
};
template<typename Arg, typename = std::enable_if_t<std::is_arithmetic<Arg>::value>>
Arg max(Arg arg){
return arg;
}
template<typename Arg, typename Arg1, typename ... Args, typename = typename std::enable_if_t<are_arithmetic<Arg, Arg1, Args...>::value>>
auto max(Arg arg, Arg1 arg1, Args ... args){
auto max_rest = max(arg1, args...);
return arg > max_rest ? arg : max_rest;
}
Теперь из этого кода я предположил, что max()
вернет максимальное число из заданного списка чисел, а также сохранит его тип.
Но когда оригинальный постер попробовал код:
int main(){
auto res = max(1.0, 2, 3.0f, 5, 7l);
std::cout << typeid(res).name() << " " << typeid(7l).name();
}
Он получил d l
из стандартного выхода
Это показывает, что возвращаемый тип функции совсем не тот, который ожидается. Почему функция не возвращает long
?
2 ответа
Мне кажется, что когда max
() функция называется как:
auto res = max(1.0, 2, 3.0f, 5, 7l);
Затем с учетом своей подписи:
auto max(Arg arg, Arg1 arg1, Args ... args){
auto max_rest = max(arg1, args...);
return arg > max_rest ? arg : max_rest;
}
Вот, Arg
очевидно, будет double
,
Тогда возвращаемое значение является троичным оператором:
return 1.0 > max_rest ? 1.0 : max_rest;
Не важно что max_rest
Завершается. Допустим, это действительно long
, Итак, у вас есть троичный оператор, с одним double
выражение, и один long
выражение.
Мне кажется, что long
Выражение будет повышен до типа double
так что возвращение auto
тип является double
,
Тип возврата
template<typename Arg, typename Arg1, typename ... Args, typename = typename std::enable_if_t<are_arithmetic<Arg, Arg1, Args...>::value>>
auto max(Arg arg, Arg1 arg1, Args ... args){
auto max_rest = max(arg1, args...);
return arg > max_rest ? arg : max_rest;
}
не зависит от значения, но от данного типа. Так что здесь он возвращает общий тип всех аргументов.