В чем разница между static_cast и Implicit_cast? - PullRequest
14 голосов
/ 15 мая 2009

Что такое implicit_cast? когда я должен предпочесть implicit_cast, а не static_cast?

Ответы [ 4 ]

19 голосов
/ 15 мая 2009

Я копирую комментарий, который я сделал, чтобы ответить на этот комментарий в другом месте.

Вы можете понижать с static_cast. Не так с implicit_cast. static_cast в основном позволяет вам выполнять любое неявное преобразование и, в дополнение к этому, обратное преобразование любого неявного преобразования (до некоторых пределов. Вы не можете снизить рейтинг, если задействован виртуальный базовый класс). Но implicit_cast будет только принимать неявные преобразования. нет приведения вниз, нет void*->T*, нет U->T, если T имеет только явные конструкторы для U.

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

int a = 3.4;

Но неявное преобразование происходит из double в int. Такие вещи, как «неявное приведение» не существуют, поскольку приведение всегда является явным запросом преобразования. Конструкция имени для boost::implicit_cast представляет собой прекрасную комбинацию «преобразования с использованием неявных преобразований». Теперь вся реализация boost::implicit_cast такова (объяснено здесь ):

template<typename T> struct identity { typedef T type; };
template<typename Dst> Dst implicit_cast(typename identity<Dst>::type t)
{ return t; }

Идея состоит в том, чтобы использовать недетерминированный контекст для параметра t. Это позволит избежать ловушек, подобных следующим:

call_const_version(implicit_cast(this)); // oops, wrong!

Хотелось написать вот так

call_const_version(implicit_cast<MyClass const*>(this)); // right!

Компилятор не может определить, какой тип должен указывать параметр шаблона Dst, потому что сначала он должен знать, что такое identity<Dst>, поскольку он является частью параметра, используемого для вывода. Но это, в свою очередь, зависит от параметра Dst (identity может быть явно специализирован для некоторых типов). Теперь у нас есть циклическая зависимость, для которой в стандарте просто говорится, что такой параметр является не выводимым контекстом, и необходимо предоставить явный аргумент шаблона.

4 голосов
/ 15 мая 2009

Предпочитайте implcit_cast, если этого достаточно в вашей ситуации. implicit_cast менее мощный и безопасный, чем static_cast.

Например, понижение с базового указателя на производный указатель возможно с static_cast, но не с implicit_cast. Обратный путь возможен с обоими забросами. Затем при приведении из базового класса к производному классу используйте implicit_cast, поскольку он защищает вас, если вы путаете оба класса.

Также имейте в виду, что implicit_cast часто не нужен. Использование no cast вообще работает в большинстве случаев, когда implicit_cast делает, отсюда и происходит «implicit». implicit_cast требуется только в особых случаях, когда тип выражения должен точно контролироваться, чтобы избежать перегрузки, например.

1 голос
/ 15 мая 2009

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

Подробнее см. Раздел 5.2.9.3 Стандарта C ++

В противном случае выражение e может быть явно преобразован в тип T с помощью static_cast вида static_- cast (e), если объявление T t (e); хорошо сформирован, для некоторых изобретен временная переменная t (8,5).

C ++ поощряет использование static_casts, потому что это делает преобразование «видимым» в программе. Само использование приведений указывает на некое принудительное правило программиста, которое стоит посмотреть, поэтому лучше использовать static_cast.

1 голос
/ 15 мая 2009

implicit_cast преобразует один тип в другой и может быть расширен путем написания неявных функций приведения для приведения из одного типа в другой.

например.

int i = 100;
long l = i;

и

int i = 100;
long l = implicit_cast<long>(i);

точно такой же код

однако вы можете предоставить свои собственные неявные приведения для ваших собственных типов, перегружая implicit_cast , как показано ниже

template <typename T>
inline T implicit_cast (typename mpl::identity<T>::type x) 
{
    return x;
}

Смотрите здесь boost / implicit_cast.hpp , чтобы узнать больше

Надеюсь, это поможет

EDIT

На этой странице также говорится о implicit_cast Новый C ++

Кроме того, основной функцией static_cast является выполнение неизменяемого или семантического преобразования из одного типа в другой. Тип меняется, но значения остаются идентичными, например,

void *voidPtr = . . .
int* intPtr = static_cast<int*>(voidPtr);

Я хочу посмотреть на этот указатель void, как если бы он был указателем int, указатель не меняется, и под прикрытием voidPtr имеет точно такое же значение, как intPtr. implicit_cast , тип изменяется, но значения после преобразования также могут отличаться.

...