C++ Converting function pointer to unique “hash” key

后端 未结 2 1244
一整个雨季
一整个雨季 2021-01-21 16:27

Se original question in the bottom.

I think I understand what you guys are saying now – that because the internal structure of the member function pointer is compiler/ma

相关标签:
2条回答
  • 2021-01-21 16:46

    You should be fine writing:

    reinterpret_cast<uintptr_t>(method)
    

    [edit] - for pointers to methods you will have to stay with c-style casts, as is explained in this SO: reinterpret_cast to void* not working with function pointers

    &method is as you suspec pointer to pointer, so its not what you want

    uintptr_t is better over int because it is guaranteed to be the same size as a pointer

    0 讨论(0)
  • 2021-01-21 17:00

    The second isn't legal: formally, you cannot convert a pointer to a function to a pointer to data (and a void* is a pointer to data). Also, you're not guaranteed to be able to convert any pointer into an int; the conversion is only legal if int is at least as large as a pointer (which means that your code should fail to compile on most 64 bit systems).

    There are several ways around this. First, on most (all?) modern machines, poitners to functions and pointers to data do have the same size and representation. (Posix requires it, in fact. Even if it wasn't the case on the first Unix machines I used.) If we assume this, you can guarantee a large enough integral type by using intptr_t, and "trick" the compiler using an additional level of indirection:

    std::pair<intptr_t, intptr_t>(
        reinterpret_cast<intptr_t>( reinterpret_cast<void*&>( object ) ),
        reinterpret_cast<intptr_t>( reinterpret_cast<void*&>( method ) ) )
    

    (This supposes that object and method are your pointers to the object and the function.)

    Note that this does not work for pointers to member functions. Pointer to member functions are completely different beasts, and I don't think that there is any effective way to use them as a key in this way (since they may, and often do, contain padding, or unset fields, in certain cases).

    For that matter, formally, this isn't really guaranteed even for normal pointers. The standard allows pointers to have don't care bits, or for several different pointer representations to compare equal. In practice, however, it is safe on most (all?) modern machines.

    0 讨论(0)
提交回复
热议问题