En C++, pouvons-nous utiliser { } pour le casting de style C ?

En C++, pouvons-nous utiliser { } pour le casting de style C ?

Oui. T{value} crée un temporaire de type T qui est direct-list-initialized avec la braced-init-list spécifiée . Cette distribution a un avantage sur T(value) dans ce T{value} peut être utilisé pour créer un tableau temporaire. Ce serait fait comme

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

Il vient également avec la mise en garde qu'une conversion restrictive est une erreur

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

La grande différence entre T(value) et (T)value est-ce en T(value) , T doit être un seul mot. Par exemple

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

Eh bien, en C++, ils veulent que vous utilisiez les casts C++ qui sont static_cast , reinterpret_cast , dynamic_cast , et const_cast . Celles-ci sont préférées à la distribution de style c car une distribution de style c fera toutes celles où les versions C++ ont certaines limitations et sont accompagnées de certaines garanties.


int(c) est la version C++ du cast de style C (int)c . Il tente d'abord un const_cast<int>(c) , puis (à défaut) un static_cast<int>(c) suivi de reinterpret_cast .

int{c} est une marmite de poisson légèrement différente. Strictement, il s'agit d'une initialisation de liste et a des règles plus strictes. En particulier, les conversions restrictives ne sont pas autorisées, c'est-à-dire

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

Par conséquent, il est recommandé de l'utiliser (plutôt que de lancer) à moins que vous ne sachiez que les conversions restrictives sont acceptables.

Pour les types autres que les types intégrés, il existe, en plus des transtypages mentionnés ci-dessus, également dynamic_cast .


Q1 :Oui. C'est presque la même chose qu'un cast de style fonctionnel (int(c) ), et fonctionne grâce à l'initialisation uniforme de c++11. Cependant, l'initialisation des accolades comporte quelques mises en garde, par exemple la réduction des conversions (comme long l = 5; char c{l}; ) générera un avertissement.

Q2 :1 et 2 sont équivalents, bien qu'il existe certaines situations où l'un fonctionne et pas l'autre.

// 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 :Le seul exemple de conversion de style C++ que vous mentionnez est static_cast . Il existe également d'autres casts C++ :

  • dynamic_cast
  • reinterpret_cast
  • const_cast