用constexpr编译时间散列 [英] Compile time hash with constexpr

查看:159
本文介绍了用constexpr编译时间散列的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在编译时创建SDBM散列的书中找到了这个示例/类。不幸的是它不能编译(无论是用C ++ 11还是用C ++ 14)。我得到错误:调用非constexpr函数。我尝试了一下,但似乎无法完成这项工作。所以这里是我的问题:


  1. 为什么它不工作,它怎么能被修复? (我很抱歉,我知道这是一个通用的问题,但至少对于一个特定的情况)

完整给你测试:

  #include< iostream> 

模板< int stringLength>
struct SDBMCalculator
{
static inline int Calculate(const char * const stringToHash,int& value)
{
int character = SDBMCalculator< stringLength - 1> ::计算(stringToHash,value);
value = character +(value <6)+(value <16) - value;
std :: cout<< static_cast< char>(character)<< std :: endl<<值<< std :: endl<<的std :: ENDL;
return stringToHash [stringLength - 1];


static inline int CalculateValue(const char * const stringToHash)
{
int value = 0;
int character = SDBMCalculator< stringLength> :: Calculate(stringToHash,value);
value = character +(value <6)+(value <16) - value;
std :: cout<< static_cast< char>(character)<< std :: endl<<值<< std :: endl<<的std :: ENDL;
返回值;
}
};

模板<>
struct SDBMCalculator< 1>
{
static inline int Calculate(const char * const stringToHash,int& value)
{
return stringToHash [0];
}
};


int main()
{
constexpr int eventID = SDBMCalculator< 5> :: CalculateValue(Hello);
std :: cout<< eventID<<的std :: ENDL;

非常感谢您的时间和精力!

解决方案

阅读错误消息:在评估constexpr值时调用非constexpr函数。您是否试过修复这个问题?



当您将所有相关函数设为 constexpr 时,您将会遇到一些额外的错误你的注意力。一些评论:


  • 请确保使用 -std = c ++ 14 。 C ++ 11不够好。

  • std :: cout 中的所有操作> SDBMCalculator 函数 - 在编译时不允许这些函数

  • 更改 int code> unsigned int 在所有相关的计算中。当左移在 int 类型上溢出时,你会得到一个未定义的行为。

     错误:移位表达式'(4723229<< 16)'溢出
    constexpr int eventID = SDBMCalculator< 5> :: CalculateValue(Hello)




通过以上所有修复,您的代码将可以正常工作。我得到结果:

  2873473298 


I have found this example/class in a book for creating SDBM hashes at compile time. Unfortunately it does not compile (neither with c++11 nor c++14). I am getting error: call to non-constexpr function. I've tried around a little bit, but I can't seem to make this work. So here is my question:

  1. Why is it not working and how could it be fixed? (I am sorry, I know it's a generic question, but at least for a very specific case)

Full (not working) example for you to test:

#include <iostream>

template <int stringLength>
struct SDBMCalculator
{
    static inline int Calculate(const char* const stringToHash, int& value)
    {
            int character = SDBMCalculator<stringLength - 1>::Calculate(stringToHash, value);
            value = character + (value << 6) + (value << 16) - value;
            std::cout << static_cast<char>(character) << std::endl << value << std::endl << std::endl;
            return stringToHash[stringLength - 1];
    }

    static inline int CalculateValue(const char* const stringToHash)
    {
            int value = 0;
            int character = SDBMCalculator<stringLength>::Calculate(stringToHash, value);
            value = character + (value << 6) + (value << 16) - value;
            std::cout << static_cast<char>(character) << std::endl << value << std::endl << std::endl;
            return value;
    }
};

template <>
struct SDBMCalculator<1>
{
    static inline int Calculate(const char* const stringToHash, int& value)
    {
            return stringToHash[0];
    }
};


int main()
{
  constexpr int eventID = SDBMCalculator<5>::CalculateValue("Hello");
  std::cout << eventID << std::endl;
}

Thanks a lot in advance for your time and effort!

解决方案

Read the error message: you are calling a non-constexpr function when evaluating a constexpr value. Have you tried fixing that?

When you make all relevant functions as constexpr you will get a few additional errors needing your attention. Some remarks:

  • Make sure you compile with -std=c++14. C++11 is not good enough for this.
  • remove all operations on std::cout from within SDBMCalculator functions - those are not permitted at compile-time
  • change int into unsigned int in all relevant computations. When left shift overflows on int type you get an undefined behavior. Left shift on unsigned type is computed modulo its maximum value+1 instead.

    error: shift expression ‘(4723229 << 16)’ overflows
    constexpr int eventID = SDBMCalculator<5>::CalculateValue("Hello")
    

With all the above fixes your code will work. I get the result:

2873473298

这篇关于用constexpr编译时间散列的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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