40 votes

Comment écrire une constante littérale comme "size_t s = 16 MByte" ?

Aujourd'hui, dans notre base de code, nous avons trouvé la ligne suivante et avons aimé son élégance pour écrire une taille de mémoire. Je me suis demandé pendant quelques minutes comment cela se compilait.

size_t poolSize = 16 MByte;

Une solution est donnée comme ma propre réponse. D'autres solutions ?

85voto

Cheers and hth. - Alf Points 59647

En C++ moderne, vous devez définir une notation littérale par exemple

auto operator""_MB( unsigned long long const x )
    -> long
{ return 1024L*1024L*x; }

Ensuite, écrivez

long const poolSize = 16_MB;

N'utilisez pas de macros, elles sont Evil™ . De bien des façons.


Disclaimer : code non touché par les mains du compilateur.

11voto

xinaiz Points 3072

Bien sûr, vous devez utiliser la métaprogrammation par modèle pour ce problème :

#include <iostream>
#include <type_traits>

template<long long N, long long M>
struct is_power_of
{ 
    static constexpr bool value = (N%M != 0)? false : is_power_of<N/M, M>::value;
};

template<long long M>
struct is_power_of<0, M> : public std::false_type { };
template<long long M>
struct is_power_of<1, M> : public std::true_type { };

template<long long N, typename = typename std::enable_if<is_power_of<N, 1024>::value>::type>
struct bytes
{
    enum {value = N, next = value * 1024};   
    template<long long M>
    struct compile_time_get
    {
        enum {value = N*M};
    };
    static long long run_time_get(long long x) {return N*x;}
};

typedef bytes<1> byte;
typedef bytes<byte::next> kilo_byte;
typedef bytes<kilo_byte::next> mega_byte;
typedef bytes<mega_byte::next> giga_byte;
typedef bytes<giga_byte::next> tera_byte;
typedef bytes<tera_byte::next> peta_byte;
typedef bytes<peta_byte::next> eksa_byte;

int main()
{
    std::cout << kilo_byte::compile_time_get<3>::value << std::endl;
    int input = 5;
    std::cout << mega_byte::run_time_get(input) << std::endl;
}

Sortie :

3072
5242880

LIVE

6voto

Martin Bonner Points 91

Si vous avez l'intention de le faire souvent, alors un littéral défini par l'utilisateur est la meilleure solution. Par contre, pour les cas uniques (et pour supporter les compilateurs plus anciens et les autres langages), je choisirais la méthode directe :

size_t poolSize = 16ul*1024*1024;

5voto

PermanentGuest Points 3267

C'était une utilisation simple et intelligente des bonnes vieilles macros.

#define KByte *1024
#define MByte *1024*1024
#define GByte *1024*1024*1024

Alors size_t poolSize = 16 MByte; est traduit en

size_t poolSize = 16 *1024*1024;

1voto

aragaer Points 3518

Tous les exemples que j'ai vus étaient plutôt du genre

#define KB 1024
#define MB (1024*1024)

size_t poolSize = 16*MB;

Pas de magie, pas de questions, ça marche tout simplement.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X