Подтвердить что ты не робот

Как написать константу литерала, такую ​​как "size_t s = 16 MByte"?

Сегодня в нашей базе кода была найдена следующая строка и понравилась ее элегантность для записи объема памяти. Несколько минут интересовался, как это компилируется.

size_t poolSize = 16 MByte;

Одно из решений дается как мой собственный ответ. Любые другие решения?

4b9b3361

Ответ 1

В современном С++ вы должны определить буквенную нотацию, например

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

Тогда напишите

long const poolSize = 16_MB;

Не используйте макросы, они Зло и торговля. Во многих отношениях.


Отказ от ответственности: код не тронут руками компилятора.

Ответ 2

Конечно, вы должны использовать метапрограммирование шаблона для этой проблемы:

#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;
}

Вывод:

3072
5242880

LIVE

Ответ 3

Если вы собираетесь делать это много, то пользовательский литерал - это путь. OTOH, для одноразовых (и для поддержки старых компиляторов и других языков), я бы пошел с прямым:

size_t poolSize = 16ul*1024*1024;

Ответ 4

Это было простое и умное использование старых добрых макросов.

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

Итак, size_t poolSize = 16 MByte; переводится в

size_t poolSize = 16 *1024*1024;

Ответ 5

Все примеры, которые я видел, были больше похожими на

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

size_t poolSize = 16*MB;

Никакая магия, никаких вопросов, просто работает.