使用constexpr将数字转换为字符串文字 [英] Convert a number to a string literal with constexpr

查看:138
本文介绍了使用constexpr将数字转换为字符串文字的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在寻找一种方法在编译时将数字转换为字符串文字。它应该看起来像这样:

I'm looking for a way to convert a number to a string literal at compile time. It should look something like this:

template <unsigned num>
struct num_to_string {
    constexpr static char value[] = /* ... magic goes here ... */;
};

因此 num_to_string< 5> :: value 等于5 {'5','\0'}

这可以用于在编译时从一个数字生成一个字符串,这是一些其他constexpr数字计算的结果。

This can be useful for generating a string at compile time from a number that is the result of some other constexpr number calculations.

还要注意,我只对 unsigned 数字感兴趣,因为这应该更容易处理。已签名版本的积分:)

Also note that I'm only interested in unsigned numbers since that should be easier to deal with. Bonus points for the signed version :)

编辑:
请注意,这类似于 C ++在编译时将整数转换为字符串,但不一样。这里我明确地希望使用constexpr而不是宏来帮助泛型编程。

Note that this is similar to C++ convert integer to string at compile time, but not the same. Here I explicitly want something that uses constexpr and not macros to aid in generic programming.

推荐答案

:)

namespace detail
{
    template<unsigned... digits>
    struct to_chars { static const char value[]; };

    template<unsigned... digits>
    const char to_chars<digits...>::value[] = {('0' + digits)..., 0};

    template<unsigned rem, unsigned... digits>
    struct explode : explode<rem / 10, rem % 10, digits...> {};

    template<unsigned... digits>
    struct explode<0, digits...> : to_chars<digits...> {};
}

template<unsigned num>
struct num_to_string : detail::explode<num> {};

一如既往,这里有一个 Coliru上的实例显示用法和(相关)生成的程序集。

As always, here's a live example on Coliru showing usage and the (relevant) generated assembly.

使用这种方法支持负数是很直接的。这是一个更通用的形式,需要用户输入整数的类型:

It's straightforward to adapt this approach to support negative numbers as well. Here's a more generic form that requires the user to input the integer's type:

namespace detail
{
    template<uint8_t... digits> struct positive_to_chars { static const char value[]; };
    template<uint8_t... digits> const char positive_to_chars<digits...>::value[] = {('0' + digits)..., 0};

    template<uint8_t... digits> struct negative_to_chars { static const char value[]; };
    template<uint8_t... digits> const char negative_to_chars<digits...>::value[] = {'-', ('0' + digits)..., 0};

    template<bool neg, uint8_t... digits>
    struct to_chars : positive_to_chars<digits...> {};

    template<uint8_t... digits>
    struct to_chars<true, digits...> : negative_to_chars<digits...> {};

    template<bool neg, uintmax_t rem, uint8_t... digits>
    struct explode : explode<neg, rem / 10, rem % 10, digits...> {};

    template<bool neg, uint8_t... digits>
    struct explode<neg, 0, digits...> : to_chars<neg, digits...> {};

    template<typename T>
    constexpr uintmax_t cabs(T num) { return (num < 0) ? -num : num; }
}

template<typename Integer, Integer num>
struct string_from : detail::explode<(num < 0), detail::cabs(num)> {};

其用法如下:

string_from<unsigned, -1>::value

Coliru上的实例

这篇关于使用constexpr将数字转换为字符串文字的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆