C ++ 17 / C ++ 2a中的编译时哈希类型

Vin*_*ent 8 c++ hash template-meta-programming c++17 c++20

考虑以下代码:

#include <iostream>
#include <type_traits>

template <class T>
constexpr std::size_t type_hash(T) noexcept 
{
    // Compute a hash for the type
    // DO SOMETHING SMART HERE
}

int main(int argc, char* argv[])
{
    auto x = []{};
    auto y = []{};
    auto z = x;
    std::cout << std::is_same_v<decltype(x), decltype(y)> << std::endl; // 0
    std::cout << std::is_same_v<decltype(x), decltype(z)> << std::endl; // 1
    constexpr std::size_t xhash = type_hash(x);
    constexpr std::size_t yhash = type_hash(y);
    constexpr std::size_t zhash = type_hash(z);
    std::cout << (xhash == yhash) << std::endl; // should be 0
    std::cout << (yhash == zhash) << std::endl; // should be 1
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

我希望type_hash函数在编译时返回该类型唯一的哈希键。有没有办法在C ++ 17或C ++ 2a中做到这一点(理想情况下仅依赖于标准,而不依赖于编译器内部函数)?

Hol*_*Cat 7

我怀疑仅使用标准C ++是否有可能。


但是有一种解决方案可以在大多数主要编译器(至少GCC,Clang和MSVC)上运行。您可以对以下函数返回的字符串进行哈希处理:

template <typename T> constexpr const char *foo()
{
    #ifdef _MSC_VER
    return __FUNCSIG__;
    #else
    return __PRETTY_FUNCTION__;
    #endif
}
Run Code Online (Sandbox Code Playgroud)


max*_*x66 5

我不知道如何获得std::size_t哈希值。

但是如果你接受一个指向某物的指针,也许你可以在模板类中获取静态成员的地址。

我的意思是......如下

#include <iostream>
#include <type_traits>

template <typename>
struct type_hash
 {
   static constexpr int          i     { };
   static constexpr int const *  value { &i };
 };

template <typename T>
static constexpr auto type_hash_v = type_hash<T>::value;


int main ()
 {
   auto x = []{};
   auto y = []{};
   auto z = x;
   std::cout << std::is_same_v<decltype(x), decltype(y)> << std::endl; // 0
   std::cout << std::is_same_v<decltype(x), decltype(z)> << std::endl; // 1
   constexpr auto xhash = type_hash_v<decltype(x)>;
   constexpr auto yhash = type_hash_v<decltype(y)>;
   constexpr auto zhash = type_hash_v<decltype(z)>;
   std::cout << (xhash == yhash) << std::endl; // should be 0
   std::cout << (xhash == zhash) << std::endl; // should be 1
 } // ...........^^^^^  xhash, not yhash
Run Code Online (Sandbox Code Playgroud)

如果你真的想要type_hash一个函数,我想你可以简单地创建一个返回type_hash_v<T>接收到的类型的函数。