gpt4 book ai didi

c++ - 用于散列编译时字符串的延迟指针

转载 作者:行者123 更新时间:2023-11-30 05:03:51 30 4
gpt4 key购买 nike

我正在尝试实现某种映射(一对元组),它使用编译时字符串作为键(对的第一个元素)。所以我想用这个 answer但是我的代码有问题:字符串在一对中。

#include <type_traits>
#include <tuple>

namespace meta {

template < typename T >
struct CType { using type = T; };


namespace detail {
template <typename T>
struct typeid_t {
using type = typename std::remove_cv<
typename std::remove_reference<T>::type
>::type;
};
}

template <typename T>
constexpr decltype(auto) typeid_(T&&) {

return CType<typename detail::typeid_t<T>::type>{};
}
}


struct HashConstString {

using value_type = uint32_t;

static constexpr uint32_t hash(const char* str) {
return str[0];
}
};


template < typename T_Hash,
typename... T_Pairs >

class UniversalMap {

template < typename T_Pair >
using U_Pair = decltype(std::make_pair(
std::integral_constant<typename T_Hash::value_type, T_Hash::hash(std::get<0>(T_Pair{}))>{},
typename decltype(meta::typeid_(std::get<1>(T_Pair{})))::type {}
));

using U_Map = decltype(std::make_tuple(
U_Pair<T_Pairs>{}...
));

private:
U_Map m_map;
};

template < typename T_Hash,
typename... T_Pairs >
constexpr decltype(auto) make_UniversalMap(T_Hash hash, T_Pairs... pairs) {

(void)hash;
((void)pairs,...);
return UniversalMap<T_Hash, T_Pairs...>();
}

int main() {

constexpr auto hashValue = HashConstString::hash("Test");
constexpr auto map = make_UniversalMap(HashConstString{},
std::make_pair("Test", meta::CType<int>{})
);
}

Wandbox

所以当字符串已经在对中时,我不知道如何正确散列字符串。因为 std::get 给我返回一个引用,这似乎是我出现取消引用的空指针错误的原因。

是否有一些“技巧”可以让这项工作在创建对之前无需计算散列?

最佳答案

问题不在于 std::get但事实上你创建了一个 const char* 的元组. "Test"衰减到 const char*当作为参数传递给 make_pair 时.不幸的是,显式指定对模板参数(例如 std::pair<const char[5], int>)不起作用,因为您无法创建数组类型的标准容器。

比较笨拙的解决方案是使用 std::array :

struct HashConstString
{
using value_type = uint32_t;
static constexpr uint32_t hash(const char *str) { return str[0]; }

// add this overload
template <std::size_t N>
static constexpr uint32_t hash(std::array<char, N> str) { return str[0]; }
};

然后像这样调用:

constexpr auto map = make_UniversalMap(HashConstString{},
std::make_pair(std::array<char, 5>{"Test"}, int{}));

避免为 std::array 指定大小你可以创建一个辅助函数:

template <std::size_t N> constexpr auto make_strarray(const char(&str)[N])
{
// unfortunately std::array<char, N>{str} does not work :(
std::array<char, N> arr{};

for (std::size_t i = 0; i < N; ++i)
arr[i] = str[i];

return arr;
}

或者因为在 C++20看起来像 std::copy将成为 constexpr:

template <std::size_t N> constexpr auto make_strarray(const char(&str)[N])
{
std::array<char, N> arr{};
std::copy(str, str + N, arr.begin());
return arr;
}

关于c++ - 用于散列编译时字符串的延迟指针,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49214852/

30 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com