2013-08-20 45 views
7

我正在学习C++ 11,并对用户定义的文字感兴趣。 所以我决定玩一下。 有些语言有这样的语法:C++ 11用户定义的文字

int n = 1000_000_000; 

我试图模拟C++ 11此功能。

inline constexpr unsigned long long operator "" _000 (unsigned long long n)noexcept 
{ 
     return n * 1000; 
} 

inline constexpr unsigned long long operator "" _000_000 (unsigned long long n)noexcept 
{ 
     return n * 1000*1000; 
} 

inline constexpr unsigned long long operator "" _000_000_000 (unsigned long long n)noexcept 
{ 
     return n * 1000*1000*1000; 
} 

int main(){ 
    constexpr auto i = 100_000; // instead of 100000 
    constexpr auto j = 23_000_000; // instead of 23000000; 
} 

但对于一般情况下,我不能模拟它,即

汽车general_case = 123_456_789; //无法编译

我的问题是“我可以使用C++ 11模拟上述一般情况吗?”。

+2

它是否适用于1_000_000?我个人会使用自定义用户文字和字母K M G(千兆兆)。 – dtech

+0

1_000_000编译!!! –

+0

@ddriver唯一的问题是,那么你不能确切的 – aaronman

回答

4

这对于C++ 11版本的语言中的用户定义文字来说是不可能的,因为它现在就是这样。用户定义的文字支持参数的有限格式,似乎不支持右侧参数,链接,此外还存在将0开头的数字表示为实际数字的问题。所以这是一个不行。

您目前的方法将_000等定义为独立文字,因此编译器只能与它们一起使用,而不能使用其他文字。它不像_是运营商,000是一些不幸的工作参数。

您可以使用字母后缀代替。

long long constexpr operator"" K (long double n) { 
    return n * 1000; 
} 
long long constexpr operator"" M (long double n) { 
    return n * 1000000; 
} 
long long constexpr operator"" G (long double n) { 
    return n * 1000000000; 
} 

然后:

0.05M == 50000; 
123.232K == 123232 
1.000000001G == 1000000001 

当然,最后一种情况排序的失败的目的,因为再一次你有没有视觉指示许多零......所以,你可以去类似:

1.G + 1 == 1000000001 // much clearer 1 billion + 1 

这使得它有点难看,因为文字需要一个实数,并且除非定义了一个额外的文字才用于整数,否则将不能用整数。然后你可以简单地使用1G。

此外,这种方法可能会产生编译器警告,显然C++组想要保留所有后面没有用“未来用途”下划线的后缀。如果您希望警告消失,请改用_K _M和_G。

编辑:我删除了初始化器列表解决方案,因为它产生了像010这样的数字的无效结果,它被处理为八进制并且弄乱了计算。

+0

是的,如果问题是多个尾随零,你就解决了这个问题,但是你没有解决它的一般情况(例如'123456789' - >'123456.789K' - >'123.456789M' - > no clear好处) –

+0

@LightnessRacesinOrbit - 我同意这是非常没有意义的,但它仍然有用作为OP的例子,谁显然文字错误。实际上我对RHS参数和链接抱有期望,看起来他们现在的文字是相当基本的。 – dtech