C++ 如何写一个像“quot;大小s=16兆字节;?

C++ 如何写一个像“quot;大小s=16兆字节;?,c++,C++,今天,在我们的代码库中,我们发现了下面这行代码,并喜欢它在编写内存大小方面的优雅。我想知道这是如何编译的 size_t poolSize = 16 MByte; 我自己给出了一个解决方案。还有其他解决方案吗?这是一个简单而巧妙地使用了好的旧宏 #define KByte *1024 #define MByte *1024*1024 #define GByte *1024*1024*1024 因此size\u t poolSize=16mbyte被翻译成 size_t poolSize = 1

今天,在我们的代码库中,我们发现了下面这行代码,并喜欢它在编写内存大小方面的优雅。我想知道这是如何编译的

size_t poolSize = 16 MByte;

我自己给出了一个解决方案。还有其他解决方案吗?

这是一个简单而巧妙地使用了好的旧宏

#define KByte *1024
#define MByte *1024*1024
#define GByte *1024*1024*1024
因此
size\u t poolSize=16mbyte被翻译成

size_t poolSize = 16 *1024*1024;
在现代C++中,你应该,例如< /P> 然后写

long const poolSize = 16_MB;
不要使用宏,它们是邪恶的™。在很多方面



免责声明:编译器不能触摸代码。

当然,您应该使用模板元编程来解决此问题:

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

如果您打算大量使用它,那么用户定义的文字就是一种方法。OTOH,对于一次性(以及支持较旧的编译器和其他语言),我会选择direct:

size_t poolSize = 16ul*1024*1024;

我看到的所有例子都更像

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

size_t poolSize = 16*MB;

没有魔法,没有问题,只有工作。

这是对宏的简单而可怕的滥用。千万不要这样做。10-15年前最好使用像
16*MBYTE
这样的东西,如果不需要在常量表达式中使用,最好将MBYTE定义为静态常量。宏的一个问题是,
var/1mbyte
并不像看上去那样将
var
除以一兆字节,而是将其乘以一兆字节。如果必须继续使用宏,至少,这应该是类似于定义KByte(x)((x)*1024)
定义MByte(x)((x)*1024*1024
,和
#定义GByte(x)((x)*1024*1024*1024)
,这样就不太可能破坏某些东西。当然,这意味着要进行一点重构,但这比误用当前宏可能发生的任何疯狂都要好。是的,这真的没有什么“聪明”的地方!100ull兆字节/16兆字节给出6871947673600,没有ull它只会溢出。小心使用。MiB会更安全accurate@TemplateRex当前位置大约15年前,我常说。但这些单位名称从未流行。我们陷入了冻结的历史,就像其他很多东西一样。除非我们坚持使用它们,否则它们就不会流行起来。将M定义为与百万不同的东西比任何宏都要糟糕。为什么要使用
无符号长
,但返回的值比
大一百万倍以上?至少返回
无符号long long
?我真希望这是个笑话。@akaltar:查找
std::ratio
/
std::chrono
。这些只是数字,那么,为什么要使用宏而不是常量呢?因为我可以在头中编写宏,然后将头包含在多个文件中,而不用担心链接器如何处理存储和其他复杂的内容。文本替换很容易理解。在
1024*1024
周围应该有括号,否则当有人
double rate=1.0/MB
时,你会有奇怪的行为。
#define
的经验法则是,如果有疑问,请始终添加额外的括号。正确。修正了。@aragaer:文本替换实际上很难合理化,尤其是调试。一个简单的
头中的static constexpr const unsigned int KB=1024
就可以了。
size_t poolSize = 16ul*1024*1024;
#define KB 1024
#define MB (1024*1024)

size_t poolSize = 16*MB;