В C++ можем ли мы использовать { } для приведения в C-Style?

Пока я читал о преобразовании типов данных, я видел этот пример:

void intval()
{
    for (char c; cin >> c; )
    cout << "the value of '" << c << "' is " << int{c} << '\n';
}

Я знаю, что мы можем использовать:

  1. int(c)
  2. (int) c
  3. static_cast<int>(c)

Мои вопросы:

Q1: есть int{c} другой способ приведения типов данных?

Q2: После некоторых исследований в сети, я знаю, что приведение C++ отличается, и он заставляет компилятор проверять возможность преобразования во время компиляции, но каковы различия между 1 и 2? И как int{c} отличается, если это просто еще один способ кастинга?

Q3: есть ли другие способы явного преобразования / приведения?

3 ответа

Решение

Является int{c} другой способ приведения типов данных?

Да. T{value} создает временный тип T инициализируется прямым списком с указанным списком фигурных скобок. Этот бросок имеет преимущество перед T(value) в этом T{value} может быть использован для создания временного массива. Это будет сделано как

int main() {
    using int_array = int[5];
    for( auto e : int_array{1,2,3,4,5})
        std::cout << e;
}

Это также идет с оговоркой, что сужение конверсии является ошибкой

int main() {
    int(10000000000ll);  // warning only, still compiles
    int{10000000000ll};  // hard error mandated by the standard
}

После некоторых исследований в сети я знаю, что приведение типов в C++ отличается, и он заставляет компилятор проверять возможность преобразования во время компиляции, но каковы различия между 1 и 2?

Большая разница между T(value) а также (T)value это в T(value), T должно быть одно слово. Например

int main() {
    unsigned int(10000000); // error
    (unsigned int)10000000; // compiles
}

Q3: есть ли другие способы явного преобразования / приведения?

Ну, в C++ они хотят, чтобы вы использовали приведения C++, которые static_cast, reinterpret_cast, dynamic_cast, а также const_cast, Они предпочтительнее приведения типов в стиле c, поскольку приведения типов в стиле ac будут выполняться все те, в которых версии C++ имеют определенные ограничения и имеют определенные гарантии.

int(c) версия C++ в стиле C (int)c, Это первые попытки const_cast<int>(c) тогда (если это не так) static_cast<int>(c)с последующим reinterpret_cast,

int{c} это немного другой скот рыбы. Строго говоря, это инициализация списка и более строгие правила. В частности, сужающие преобразования не допускаются, т.е.

int x;
char s{x};  // error

Поэтому рекомендуется использовать это (а не приведение), если только вы не знаете, что сужающие преобразования являются приемлемыми.

Для других типов, кроме встроенных, в дополнение к приведенным выше приведениям также dynamic_cast,

Q1: да. Это почти так же, как в функциональном стиле (int(c)), и работает из-за равномерной инициализации C++11. Однако инициализация скобки имеет несколько предостережений, например, сужение конверсий (например, long l = 5; char c{l};) сгенерирует предупреждение.

Q2: 1 и 2 эквивалентны, хотя в некоторых ситуациях одна работает, а другая - нет.

// long long(c); // Breaks unless you make a typedef for 'long long'
(long long)c;    // Works fine

template <class In, class Out>
Out convert(const In& in) {
    // return (Out)in; // Only works if 'In' is a primitive type
    return Out(in);    // Works regardless of the type of 'In' (assuming an appropriate constructor exists)
}

Q3: единственный пример кастинга в стиле C++, который вы упомянули, static_cast, Также есть другие приведения C++:

  • dynamic_cast
  • reinterpret_cast
  • const_cast
Другие вопросы по тегам