C++ 指向哈希编译时字符串的延迟指针

C++ 指向哈希编译时字符串的延迟指针,c++,string,hash,metaprogramming,std-pair,C++,String,Hash,Metaprogramming,Std Pair,我试图实现某种映射(成对的元组),它使用编译时字符串作为键(成对的第一个元素)。所以我想使用它,但是我的代码有一个问题:字符串在一对中 #include <type_traits> #include <tuple> namespace meta { template < typename T > struct CType { using type = T; }; namespace detail { template <

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

#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>{})
    );
}
#包括
#包括
命名空间元{
模板
结构CType{using type=T;};
名称空间详细信息{
模板
结构类型ID\u t{
使用type=typename std::删除<
typename std::remove_reference::type
>::类型;
};
}
模板
constexpr decltype(自动)typeid_Ut&&{
返回CType{};
}
}
结构HashConstString{
使用值\u type=uint32\u t;
静态constexpr uint32\u t散列(const char*str){
返回str[0];
}
};
模板
类通用地图{
模板
使用U_对=decltype(std::make_对(
std::积分_常数{},
typename decltype(meta::typeid(std::get(T_Pair{}))::type{}
));
使用U_Map=decltype(std::make_tuple)(
U_对{}。。。
));
私人:
U_图m_图;
};
模板
constexpr decltype(自动)生成通用映射(T_哈希哈希,T_对…对){
(无效)散列;
((无效)对,…);
返回UniversalMap();
}
int main(){
constexpr auto hashValue=HashConstString::hash(“测试”);
constexpr auto map=make_UniversalMap(HashConstString{},
std::make_pair(“Test”,meta::CType{})
);
}

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


是否有一些“技巧”可以在创建对之前不必计算哈希就完成这项工作?

问题不在于
std::get
,而是在于您创建了一个
const char*
的元组<代码>“测试”在作为参数传递给
make\u pair
时衰减为
const char*
。不幸的是,显式指定对模板参数(例如,
std::pair
)不起作用,因为您无法创建类型为array的std容器

比较尴尬的解决方案是使用
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]; }
};
或者,因为在
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;
}
template constexpr自动生成字符串(const char(&str)[N])
{
std::数组arr{};
复制(str,str+N,arr.begin());
返回arr;
}
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;
}
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;
}