Compile-time constant id

前端 未结 16 2138
不知归路
不知归路 2020-12-02 20:06

Given the following:

template
class A
{
public:
    static const unsigned int ID = ?;
};

I want ID to generate a unique c

相关标签:
16条回答
  • 2020-12-02 20:39

    Another alternative is to consider the following class Data with the unique, static member field type:

    template <class T>
    class Data
    {
    public:
        static const std::type_index type;
    };
    // do [static data member initialization](http://stackoverflow.com/q/11300652/3041008)
    // by [generating unique type id](http://stackoverflow.com/q/26794944/3041008)
    template <class T>
    std::type_index const Data<T>::type = std::type_index(typeid(T));
    

    produces the output (MinGWx64-gcc4.8.4 -std=c++11 -O2)

    printf("%s %s\n", Data<int>::type.name(), Data<float>::type.name())
    //prints "i f"
    

    It's not exactly an integer id or pretty-printable string, nor a constexpr, but can be used as an index in (un)ordered associative containers.
    It also appears to work if the Data.h header is included in multiple files (same hashCode() values).

    0 讨论(0)
  • 2020-12-02 20:41

    I encountered this exact problem recently. My solution:

    counter.hpp

    class counter
    {
        static int i;
        static nexti()
        {
            return i++;
        }
    };
    

    Counter.cpp:

    int counter::i = 0;
    

    templateclass.hpp

    #include "counter.hpp"
    
        template <class T>
        tclass
        {
            static const int id;
        };
    
        template <class T>
        int tclass<T>::id = counter::nexti();
    

    It appers to work properly in MSVC and GCC, with the one exception that you can't use it in a switch statement.

    For various reasons I actually went further, and defined a preprocessor macro that creates a new class from a given name parameter with a static ID (as above) that derives from a common base.

    0 讨论(0)
  • 2020-12-02 20:41
    template<typename T>
    static void get_type_id() { void* x; new (x) T(); }
    using type_id_t = void(*)();
    

    works fine with optimizations

    0 讨论(0)
  • 2020-12-02 20:47

    This can't be done. An address to a static object is the closest you can get to a unique id, however in order to take addresses of such objects (even static const integrals) they must be defined somewhere. Per the one definition rule, they should be defined within a CPP file, which cannot be done since they are templates. If you define the statics within a header file, then each compilation unit will get its own version of it implemented of course at different addresses.

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