web-dev-qa-db-fra.com

Quel est le but de std :: to_integer?

Pour autant que je sache, std::to_integer<T> Est équivalent à T(value)value est une variable de type std::byte.
J'ai examiné certaines implémentations des principaux compilateurs et j'ai constaté que dans ce cas équivalent signifie littéralement implémenté comme. En d'autres termes, la plupart du temps to_integer Est en fait implémenté comme:

return T(value);

Et c'est tout.

Ce que je ne comprends pas, c'est quel est le but d'une telle fonction?
Ironiquement, les inconvénients sont encore plus que les avantages. Je devrais inclure un en-tête entier pour une telle fonction juste pour éviter une distribution de type C qui est très probablement directement en ligne de toute façon.

Y a-t-il une autre raison à cela ou c'est juste vraiment une alternative Nice pour un casting en C et rien de plus?

9
skypjack

c'est vraiment une belle alternative pour un casting en C et rien de plus?

Vous dites cela comme s'il s'agissait d'un détail insignifiant.

Les lancers sont dangereux. Il est facile de convertir quelque chose dans le mauvais type, et souvent les compilateurs ne vous empêcheront pas de faire exactement cela. De plus, comme std::byte N'est pas un type intégral en C++, travailler avec des valeurs d'octets numériques nécessite souvent une quantité de transtypage. Le fait d'avoir une fonction qui se convertit explicitement en nombres entiers rend l'expérience utilisateur plus sûre.

Par exemple, float(some_byte) est parfaitement légal, tandis que to_integer<float>(some_byte) est explicitement interdit. to_integer<T> Nécessite que T soit un type intégral.

to_integer Est une alternative plus sûre.

Je devrais inclure un en-tête entier pour une telle fonction

Si par "en-tête entier", vous voulez dire le même en-tête vous avez obtenu std::byte Et donc déjà par définition inclus ...

12
Nicol Bolas

std::to_integer<T>(some_byte) est équivalent à T(some_byte) s'il compile réellement . T(some_byte) est équivalent à la conversion de style C non sécurisée de (T)some_byte, qui peut faire des choses effrayantes . D'autre part, std::to_integer est convenablement contraint de ne fonctionner que lorsqu'il est sûr:

Cette surcharge ne participe à la résolution de la surcharge que si std::is_integral_v<IntegerType> est vrai.

Si le T n'était pas réellement un type entier, plutôt que d'avoir potentiellement un comportement indéfini, le code ne sera pas compilé. Si la some_byte n'était pas réellement un std::byte, plutôt que d'avoir potentiellement un comportement non défini, le code ne se compilera pas.

9
Justin

Au-delà de l'expression des problèmes d'intention et de sécurité déjà mentionnés, je retiens de la discussion du comité sur le document que c'est censé être comme std::to_string et pourrait avoir plus de surcharges à l'avenir.

3
Davis Herring

Une conversion de style C n'est pas équivalente à std::to_integer<T>. Voir l'exemple ci-dessous.

std::to_integer<T> ne participe à la résolution des surcharges que si std::is_integral_v<T> est vrai.

#include <cstddef>
#include <iostream>

template <typename T>
auto only_return_int_type_foo(std::byte& b)
{
    return std::to_integer<T>(b);
}

template <typename T>
auto only_return_int_type_bar(std::byte& b)
{
    return T(b);
}

int main()
{
    std::byte test{64};
    // compiles
    std::cout << only_return_int_type_foo<int>(test) << std::endl;

    // compiler error
    std::cout << only_return_int_type_foo<float>(test) << std::endl;

    // compiles
    std::cout << only_return_int_type_bar<int>(test) << std::endl;

    // compiles
    std::cout << only_return_int_type_bar<float>(test) << std::endl;
} 
2
Fibbles