将短字符串转换为32位整数的最有效方法是什么?

时间:2017-12-23 09:49:16

标签: c++ string c++11 integer constexpr

出于许多目的,打包成无符号32位整数的短字符串/字符数组非常有用,因为它们可以一次性比较,只需进行简单的整数比较,并在switch语句中使用,保持一点人类可读性。

将这些短字符串转换为32位整数的最常用方法是移位/或:

#include <stdint.h>

uint32_t quadchar( const char* _str ) 
{

    uint32_t result = 0;

    for( size_t i=0; i<4; i++ )
    {
        if( _str[i] == 0 )
           return result;
        result = (result << 8) | _str[i];
    }

    return result;
}

字符串太长,会被截断。

到目前为止一直很好,但这必须在运行时完成,这需要花费一些时间。 是否也可以在编译时执行此操作?

2 个答案:

答案 0 :(得分:1)

不需要细节辅助函数:您可以使用默认值。

并且不需要双三元运算符:您可以通过单个测试完成所有操作

std::uint32_t inline constexpr quadchar (char const * input, 
                                         std::size_t idx = 0U,
                                         std::uint32_t result = 0U) 
 {
   return (idx < 4U) && *input
      ? quadchar(input+1, idx+1U, (result << 8) | *input)
      : result;
 }

但是,为了使它更具便携性和通用性,我建议

1)使用sizeof()代替4 idx限制

2)使用CHAR_BIT代替8进行result转换(请记住包括&#34; <climits>&#34;)

3)使用std::uint32_t类型的模板类型(如果需要,默认为result。)

这样的东西
template <typename I = std::uint32_t>
constexpr inline I ichar (char const * input, 
                          I result = 0U,
                          std::size_t idx = 0U)
 {
   return (idx < sizeof(I)) && *input
      ? ichar(input+1, idx+1U, (result << CHAR_BIT) | *input)
      : result;
 }

你可以打电话

constexpr auto u32 = ichar(ptr);

当您需要std::uint32_t或(例如)

constexpr auto u64 = ichar<std::uint64_t>(ptr);

用于其他返回类型。

答案 1 :(得分:0)

从C ++ 11开始,可以使用constexpr specifier在运行时以零成本编译时执行此操作。

namespace Internal 
{
    uint32_t inline constexpr quadchar( char const *_input, 
        uint8_t _idx, uint32_t _result ) 
    {
        return _idx == 4 ? _result 
            : *_input ? quadchar ( _input+1, _idx + 1, (_result << 8) | *_input ) 
                : _result;
    }
}

uint32_t inline constexpr quadchar( char const *_input ) {
    return Internal::quadchar( _input, 0, 0 );
}

我已将实现重载放入内部命名空间以将其隐藏起来。语法不像上面的运行时示例那样好,因为你不能在if中使用constexpr,但我认为这是值得的。