Compile-time constant id

前端 未结 16 2142
不知归路
不知归路 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条回答
  •  -上瘾入骨i
    2020-12-02 20:23

    Ok.....so this is a hack that I found from this website. It should work. The only thing you need to do is add another template parameter to your struct that takes a counter "meta-object". Note that A with int, bool and char all have unique IDs, but it is not guaranteed that int's will be 1 and bool will be 2, etc., because the order in which templates are initiated is not necessarily known.

    Another note:

    This will not work with Microsoft Visual C++

    #include 
    #include "meta_counter.hpp"
    
    template
    struct A
    {
        static const size_t ID = counter::next();
    };
    
    int main () {
        typedef atch::meta_counter counter;
        typedef A AInt;
        typedef A AChar;
        typedef A ABool;
        switch (ABool::ID)
        {
            case AInt::ID:
                std::cout << "Int\n";
                break;
            case ABool::ID:
                std::cout << "Bool\n";
                break;
            case AChar::ID:
                std::cout << "Char\n";
                break;
        }
    
        std::cout << AInt::ID << std::endl;
        std::cout << AChar::ID << std::endl;
        std::cout << ABool::ID << std::endl;
        std::cout << AInt::ID << std::endl;
        while (1) {}
    }
    

    Here is meta_counter.hpp:

    // author: Filip Roséen 
    // source: http://b.atch.se/posts/constexpr-meta-container
    
    #ifndef ATCH_META_COUNTER_HPP
    #define ATCH_META_COUNTER_HPP
    
    #include 
    
    namespace atch { namespace {
    
      template
      struct meta_counter {
        using size_type = std::size_t;
    
        template
        struct ident {
          friend constexpr size_type adl_lookup (ident);
          static constexpr size_type value = N;
        };
    
        // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 
    
        template
        struct writer {
          friend constexpr size_type adl_lookup (Ident) {
            return Ident::value;
          }
    
          static constexpr size_type value = Ident::value;
        };
    
        // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 
    
        template {})>
        static constexpr size_type value_reader (int, ident) {
          return N;
        }
    
        template
        static constexpr size_type value_reader (float, ident, size_type R = value_reader (0, ident ())) {
          return R;
        }
    
        static constexpr size_type value_reader (float, ident<0>) {
          return 0;
        }
    
        // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 
    
        template
        static constexpr size_type value (size_type R = value_reader (0, ident {})) {
          return R;
        }
    
        template
        static constexpr size_type next (size_type R = writer>::value) {
          return R;
        }
      };
    }}
    
    #endif /* include guard */
    

提交回复
热议问题