出于许多目的,打包成无符号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;
}
字符串太长,会被截断。
到目前为止一直很好,但这必须在运行时完成,这需要花费一些时间。 是否也可以在编译时执行此操作?
答案 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
,但我认为这是值得的。