0
votes

I have the function hash_constexpr that takes in a const char* and returns a hash using a novel algorithm. The hash_constexpr function should be generating the hash at compile time.

namespace detail
{
    template<size_t Count>
    inline constexpr size_t countof(const char(&string)[Count])
    {
        return Count - 1;
    }

    template<typename T>
    struct ascii_hash_t
    {
        template<typename L>
        static constexpr T f(L const& data, T hash, size_t i = 0)
        {
            return i < countof(data) ? f(data, (hash & (~0u)) ^ (hash << 7) ^ T(data[i]), i + 1) : hash;
        }
    };

    template<typename T, typename L>
    inline constexpr T generate_ascii_hash(L const& data)
    {
        return detail::ascii_hash_t<T>::f(data, 0);
    }
};

template<size_t Count>
inline constexpr uint32_t hash_constexpr(const char(&string)[Count])
{
    return detail::generate_ascii_hash<uint32_t>(string);
}

My issue is that it appears that the hash_constexpr function doesn't appear to actually be returning a constexpr value. When I invoke it like so:

constexpr uint32_t asd = hash_constexpr("asdasd");

I get the following error:

Constexpr variable 'asd' must be initialized by a constant expression

What am I doing wrong?

EDIT #1:

Note that this call is working correctly:

constexpr int32_t countof_test = detail::countof("hello");

EDIT #2:

It appears that this call is working correctly as well:

constexpr int32_t generate_ascii_hash_test = detail::generate_ascii_hash<int32_t>("asd");
1
shouldn't ascii_hash_t::f be constexpr? - Vittorio Romeo
You just fixed your own bug by making f constexpr. - Howard Hinnant
It is now, just noticed that it wasn't, but I still get the same error. :( - Colin Basnett
I don't get the error with your recent fix, and did without it. - Howard Hinnant
Hm, what compiler are you using? I'm using XCode 4.6.1's compiler. - Colin Basnett

1 Answers

0
votes

The issue is that the function ascii_hash_t::f, for the specific template instantiation is not a constexpr. This prevents you from performing the operation as a constexpr.

See http://ideone.com/heFuFP for an example if it working as you expect.