什么阻止在编译时评估constexpr?

时间:2016-12-07 08:37:21

标签: c++ c++11 template-meta-programming constexpr

考虑以下代码:

#include <unordered_set>
#include <type_traits>
#include <cstring>

constexpr auto cstring_hash(const char* istring) -> size_t {
    return (*istring) == '\0' ?
        size_t(0):
        (*istring) + cstring_hash(istring + 1);
}

constexpr auto cstring_length(const char* istring) -> size_t {
    return (*istring) == '\0' ?
        size_t(0):
        size_t(1) + cstring_length(istring + 1);
}

class PrehashedString {
public:
    constexpr PrehashedString(const char* istring) 
    : str_(istring)
    , hash_(cstring_hash(istring))
    , size_(cstring_length(istring)) {
    }
    constexpr auto& get_hash() const { return hash_; }
    auto operator==(const PrehashedString& iother) const {
        return 
            size_ == iother.size_ &&
            std::strcmp(str_, iother.str_) == 0;
    }
private:
    const char* str_;
    size_t hash_;
    size_t size_;
};

namespace std {
template <>
struct hash<PrehashedString> {
constexpr auto operator()(const PrehashedString& ihashed_string) const -> size_t {
    return ihashed_string.get_hash();
}
};
}

为什么hash0创建str0的位置)在hash1(其中str1auto func0() { const auto str0 = PrehashedString("my_string_0"); const auto hash0 = str0.get_hash(); const auto& str1 = PrehashedString("my_string_1"); const auto hash1 = str1.get_hash(); return hash0 + hash1; } 创建时在运行时进行评估 reference )在编译时得到评估? 我已经在 MSVC GCC 6.2 / 7.0 中尝试了它,看起来它们都失败了。它是否在标准中阻止在编译时对其进行评估?

auto func1(std::unordered_set<PrehashedString>& iset) {
  return iset.count("my_key");
}

进一步扩展它,如何在编译时强制使用constexpr函数进行评估:

(template <size_t N> PrehashedString(const char (&istring)[N]){...})

注意: 我知道如何通过使构造函数只接受字符串文字'',并利用字符串文字长度作为哈希函数的模板参数来实现这一点,我只是好奇它失败的原因。

0 个答案:

没有答案