В C++ можем ли мы использовать { } для приведения в C-Style?
Пока я читал о преобразовании типов данных, я видел этот пример:
void intval()
{
for (char c; cin >> c; )
cout << "the value of '" << c << "' is " << int{c} << '\n';
}
Я знаю, что мы можем использовать:
int(c)
(int) c
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