为了账号安全,请及时绑定邮箱和手机立即绑定

编译时间字符串散列

编译时间字符串散列

C++
汪汪一只猫 2019-09-19 16:42:30
我在几个不同的地方读过,使用C ++ 11的新字符串文字,可以在编译时计算字符串的哈希值。然而,似乎没有人准备出来说它将是可能的或如何完成。这可能吗?操作员会是什么样子?我特别感兴趣的是这样的用例。void foo( const std::string& value ){   switch( std::hash(value) )   {      case "one"_hash: one(); break;      case "two"_hash: two(); break;      /*many more cases*/      default: other(); break;   }}注意:编译时哈希函数不必像我编写的那样完全。我尽力猜测最终解决方案的样子,但meta_hash<"string"_meta>::value也可能是一个可行的解决方案。
查看完整描述

3 回答

?
杨魅力

TA贡献1811条经验 获得超5个赞

至少在我阅读§7.1.5/ 3和§5.19时,以下内容可能是合法的:


unsigned constexpr const_hash(char const *input) {

    return *input ?

        static_cast<unsigned int>(*input) + 33 * const_hash(input + 1) :

        5381;

}

这似乎遵循§7.1.5/ 3中的基本规则:


形式是:“回归表达”;

它唯一的参数是一个指针,它是一个标量类型,因此是一个文字类型。

它的返回是unsigned int,它也是标量(因此是字面的)。

没有隐式转换为返回类型。

有一些问题是*inputs 是否涉及非法左值转换,我不确定我是否理解§5.19/ 2/6/2 1和§4.1中的规则以确保这一点。


从实际的角度来看,这个代码被(例如)g ++接受,至少可以追溯到g ++ 4.7.1。


用法如下:


switch(std::hash(value)) {

    case const_hash("one"): one(); break;

    case const_hash("two"): two(); break;

    // ...

    default: other(); break;

}

为了符合§5.19/ 2/6/2的要求,您可能需要执行以下操作:


// one of the `constexpr`s is probably redundant, but I haven't figure out which.

char constexpr * constexpr v_one = "one"; 


// ....


case const_hash(v_one): one(); break;

我正在使用额外的'斜线'数字来指代未编号的子弹点,所以如果是第5.19 / 2节中的第六个要点,这是内部的第二个要点。我想我可能要和Pete Becker讨论是否可以在层次结构中添加某种数字/字母/罗马数字来识别这样的部分......


查看完整回答
反对 回复 2019-09-19
  • 3 回答
  • 0 关注
  • 457 浏览

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信