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

问题描述 投票:1回答:2

出于许多目的,打包成无符号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;
}

字符串太长,会被截断。

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

c++ string c++11 integer constexpr
2个回答
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转换(记得包括“<climits>”)

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);

对于其他返回的类型。


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,但我认为这是值得的。

© www.soinside.com 2019 - 2024. All rights reserved.