Pourquoi `decltype (static_cast <T> (…))` n'est pas toujours `T`?


24

Pour le code suivant, toutes les assertions sauf la dernière passent:

template<typename T>
constexpr void assert_static_cast_identity() {
    using T_cast = decltype(static_cast<T>(std::declval<T>()));
    static_assert(std::is_same_v<T_cast, T>);
}

int main() {
    assert_static_cast_identity<int>();
    assert_static_cast_identity<int&>();
    assert_static_cast_identity<int&&>();
    // assert_static_cast_identity<int(int)>(); // illegal cast
    assert_static_cast_identity<int (&)(int)>();
    assert_static_cast_identity<int (&&)(int)>(); // static assert fails
}

Pourquoi cette dernière assertion échoue-t-elle et static_cast<T>ne renvoie- Tt- elle pas toujours un ?


J'ajoute que T_cast i{1};je reçois invalid initialization of non-const reference of type 'T_cast' {aka 'int (&)(int)'} from an rvalue of type '<brace-enclosed initializer list>', donc pour une raison quelconque, T_castc'est un int (&)(int)plutôt qu'un int (&&)(int).
Kevin

Réponses:


21

Ceci est codé en dur dans la définition de static_cast:

[expr.static.cast] (c'est moi qui souligne)

1 Le résultat de l'expression static_­cast<T>(v)est le résultat de la conversion de l'expression ven type T. Si Test un type de référence lvalue ou une référence rvalue au type de fonction, le résultat est un lvalue ; si Test une référence rvalue au type d'objet, le résultat est une valeur x; sinon, le résultat est une valeur. L' static_­cast opérateur ne doit pas rejeter la constance.

decltype respecte la catégorie de valeur de son opérande et produit une référence lvalue pour les expressions lvalue.

Le raisonnement peut être dû au fait que les noms de fonctions eux-mêmes sont toujours des valeurs l, et donc une valeur r d'un type de fonction ne peut pas apparaître "à l'état sauvage". En tant que tel, le casting sur ce type n'a probablement aucun sens.


cette question aborde plus en détail "les valeurs [r] d'un type de fonction [n'apparaissent] pas" dans la nature ""
Eric
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.