2016-05-28 6 views
6

Какова наилучшая практика для кастинга между разными типами чисел? Типы float, double, int - это те, которые я использую больше всего на C++.Лучшая практика в C++ для литья между типами чисел

Пример из вариантов, где f представляет собой float и n является double или int:

float f = static_cast<float>(n); 
float f = float(n); 
float f = (float)n; 

Я обычно пишу static_cast<T>(...) но интересуется, есть ли какой-либо консенсус в сообществе разработчиков C++, если есть предпочтительный способ.

Я знаю, что у этого вопроса есть cropped up в отношении кастинга в целом, однако меня интересуют конкретно цифры и есть ли конкретные рекомендации в подходе для типов номеров.

+0

Используйте «static_cast», «стандартный» C++ путь, и ничего не изменилось с C++ 11. – songyuanyao

+3

Лучшей практикой было бы написать программу, которая не нуждалась бы в каких-либо приведениях – Drop

+0

'float f = n;' является моим предпочтением –

ответ

4

Просто используйте static_cast. Проблема с C-кастами - неоднозначность операции (т. Е. Точка (1) Explicit type conversion).

C++ casts избегает этого. Кроме того, при поиске их более заметны C++.

Использование слов Страуструпа (What good is static_cast?):

Даже невинный вид броска может стать серьезной проблемой, если в процессе разработки или технического обслуживания, один из типов, участвующих изменяется. Например, что это значит ?:

x = (T)y; 

Мы не знаем. Это зависит от типа T и типов x и y. T может быть именем класса, typedef или параметром шаблона. Возможно, x и y являются скалярными переменными, а (T) представляет собой преобразование значений. Возможно, x относится к классу, полученному от класса y, и (T) является подавленным. Возможно, x и y являются несвязанными типами указателей. Поскольку C-style cast (T) может использоваться для выражения многих логически различных операций, у компилятора есть только самый лучший шанс поймать злоупотребления. По той же причине программист может не знать точно, что делает бросок. Это иногда считается преимуществом новичков-программистов и является источником тонких ошибок, когда новичок догадывается неправильно.

Были введены «отливки нового стиля», чтобы дать программистам возможность более четко изложить свои намерения и компилятор поймать больше ошибок.

[CUT]

Вторичная причиной для введения бросания нового стиля был то, что слепки С-типа очень трудно обнаружить в программе. Например, вы не можете удобно выполнять поиск при помощи обычного редактора или текстового редактора.

[CUT]

проливает на самом деле главным образом избежать в современных C++

Также рассмотреть boost::numeric::converter/boost::numeric_cast, которые являются более безопасными альтернативами (часть Boost.NumericConversion библиотеки).

E.g.

#include <iostream> 
#include <boost/numeric/conversion/cast.hpp> 

int main() 
{ 
    using boost::numeric_cast; 

    using boost::numeric::bad_numeric_cast; 
    using boost::numeric::positive_overflow; 
    using boost::numeric::negative_overflow; 

    try 
    { 
    int i = 42; 
    short s = numeric_cast<short>(i); // This conversion succeeds (is in range) 
    } 
    catch(negative_overflow &e) { std::cout << e.what(); } 
    catch(positive_overflow &e) { std::cout << e.what(); } 

    return 0; 
} 

В общем для обоих неявных преобразований и явных преобразований (через static_cast) отсутствие сохранения диапазона делает преобразования между числовыми типами ошибок.

numeric_cast обнаруживает потерю диапазона при преобразовании числового типа и генерирует исключение, если диапазон не может быть сохранен.

+0

"* Иногда это конверсия ... иногда это актерский состав *, не имеет для меня никакого смысла. Листинг - это явное преобразование, не так ли ?. – user2079303

+0

@ user2079303 Вы правы: это «терминология Google» (https://google.github.io/styleguide/cppguide.html#Casting), но это точно не соответствует регулярному использованию C++ (http://stackoverflow.com/ д/4337306/3235496). Я изменил эту линию, чтобы избежать недоразумений. – manlio

+0

Спасибо за ссылку. Это поможет, когда я буду спорить с этой терминологией в будущем. Слишком плохо, что руководство не объясняет разницу между актом и конверсией в их терминологии. – user2079303

0

Как правило, эти литейные операторы классифицируются по двум основным группам: конкретных операторов литья и традиционных операторов литья. cplusplus.com объясняет это следующим образом:

... Для того, чтобы контролировать эти типы переходов между классами, мы имеем четыре конкретных операторов литья: dynamic_cast, reinterpret_cast, static_cast и const_cast. Их формат состоит в том, чтобы следовать новому типу, заключенному между угловыми скобками (<>), и сразу же после этого выражение должно быть преобразовано между круглыми скобками.

dynamic_cast <new_type> (expression)

reinterpret_cast <new_type> (expression)

static_cast <new_type> (expression)

const_cast <new_type> (expression)

традиционного типа литья эквиваленты этих выражений будет:

(new_type) expression

new_type (expression)

, но каждый со своими особыми характеристиками.

Во время работы над задачей, мы (почти) все используют конкретные отливки. Рассмотрев советы, это как-то зависит от вас.

См. resource.

Смежные вопросы