TGViewer
Грокаем C++ Грокаем C++ @grokaemcpp · 9.35K subscribers
Post #255 3.6K
​static_cast

В предыдущих статьях мы несколько раз упоминали оператор static_cast, поэтому мы решили затронуть еще и тему приведения типов. По мере развития серии, рассмотрим каждый из них, а завершим разбором C-style cast.

Исходя из своих наблюдений, наиболее востребованным оператором приведения является static_cast, т.к. в основном большинство приходится на преобразование между совместимыми друг с другом типами:
int32_t value_i32 = 42;
int64_t value_i64 = static_cast<int64_t>(value_i32);

float value_f32 = 42.314;
int16_t value_i16 = static_cast<int16_t>(value_f32);

Оператор static_cast так же проверяет корректность выполняемого приведения. Например, запрещает приведение указателя к значению:
// error: invalid 'static_cast' from type 'int*' to type 'int'
static_cast<int>(&value);

Конечно, некоторые смысловые ошибки нельзя поймать, ведь с точки зрения типа, все хорошо. Например, приведение значения к enum class может привести к непредвиденным сценариям 🤭:
enum class action_e : int { RUN = 0, FIGHT = 1 };

// Should I run or fight?
action_e action = static_cast<action_e>(2);

Лучше бы их все таки дополнять еще debug-only assert или вообще условным ветвлением.

Правила приведения для фундаментальных (встроенных) типов в C++ определены заранее, а вот для пользовательских классов можно определить свои собственные преобразования с помощью оператора приведения к типу: operator Type():
class specific_error_t
{
...
// Оператор приведение к типу `bool`
operator bool() const
{
return m_code < 0;
}
...
};

Эта ручка будет дергаться при явном и неявном приведении типов в живом примере 1:
specific_error_t internal_code = -1;

// Приведение `internal_code` к типу `bool`
bool has_internal_code = static_cast<bool>(internal_code);

Один из неочевидных способов применения этого оператора является приведение к типу void. Казалось бы, зачем? Но это помогает подавить предупреждение компилятора о неиспользуемой переменной / не присвоенном значении:
void foo()
{
    int result = read_and_do_something();

#ifdef DEBUG
    // Debug build check only
    assert(result == 0);
#endif

    static_cast<void>(result);
}


Если такое предупреждение появляется, то вероятно, что что-то вы все таки упускаете в своем коде. Но иногда такие ситуации встречаются, когда полезная нагрузка от вашего действия есть, а предупреждение не к месту. Например, в следствие какой-нибудь препроцессорной директивы. Напоминаем, что в C++17 так же есть атрибут [[maybe_unused]], который решает эту проблему.

Так же static_cast позволяет выполнить приведение к типу родительского класса (upcasting) и к типу наследников (downcasting) в рамках одной иерархии классов:
Child *pointer   = new Child();

// Upcasting
Base *base_ptr = static_cast<Base*>(pointer);

// Downcasting
Child *child_ptr = static_cast<Child*>(base_ptr);

Важным моментом является тот факт, что static_cast не может обеспечить проверку корректности совершенного преобразования к наследнику (downcasting)! Если наследник выбран неправильно и вы допустили ошибку преобразования к другому типу, то вам все равно дадут скомпилироваться: живой пример 2. У компилятора действительно не хватает информации, чтобы это проверить на этапе компиляции.

Разберем эту тему подробнее, когда дойдем до динамического полиморфизма
  • 👍 23
  • ✍ 16
  • 🔥 3
  • ❤ 2
More from @grokaemcpp
  1. Oct 14, 2026​​Что внутри std::condition_variable? #опытным Более менее все знакомы с примитивом синхро…
  2. Oct 12, 2026​​WAT #новичкам Как вы думаете, результат выражения: bool math = -1 < 1U; будет правдой ил…
  3. Oct 8, 2026​​Strict weak ordering #опытным На первый взгляд, всё выглядит рабочим: мы создаём 40 зака…
  4. Oct 7, 2026​​Где-то баг... #опытным Вот вам код: struct Order { int price; int id; }; int main() { st…
  5. Oct 5, 2026Откуда spurious wakeup на кондваре? #опытным У кондваров есть метод std::condition_variabl…
  6. Oct 1, 2026​​Stacktrace. Tips #опытным Чтобы полноценно работать со стандартными трейсами, нужно знат…
Threads Profile ViewerView any public Threads profile without an account.Open ThreadLook →Writing with AI? Make it sound human.Metric37 rewrites AI drafts so they read naturally. Free AI detector, 1,500 words free.Try Metric37 →