3

I would like to code a bijection between int and C++ trivial type such as double or float.

The bijection is known at compile time.

I would like to use it like this (caps denotes a macro):

INIT(42,float)
INIT(-17,double)

#include <type_traits>

int main() {
    const int a = TYPE_TO_INT(float);
    static_assert(a==42);
    INT_TO_TYPE(-17) pi;
    static_assert(std::is_same<double,decltype(pi)>::value);
    return 0;
}
Alessandro Jacopson
  • 18,047
  • 15
  • 98
  • 153
  • Related: [Is there an inverse function for typeid in C++17?](https://stackoverflow.com/questions/58904739/is-there-an-inverse-function-for-typeid-in-c17) – Brian61354270 Apr 07 '21 at 18:25
  • 1
    May I ask what problem you are trying to solve with this? [This](https://stackoverflow.com/questions/16490835/how-to-build-a-compile-time-key-value-store) might help, but I'm not sure how'd you get a type back out of it generically – NathanOliver Apr 07 '21 at 18:28
  • @NathanOliver actually, after re-reading my question, maybe I do not need a bidirectional map :-). I need to keep together an `int` and a type, stuff related to OpenCV where you specify the number of bit per pixel with an `int` and the type of the pixel value with a C type. For example an image with `float` pixel has a depth of `32` and sometimes you need the `float`, sometimes you need the `32`. – Alessandro Jacopson Apr 08 '21 at 17:56

1 Answers1

10

You can expand INIT if you want to avoid macros but it does nicely clean up the boilerplate:

template <typename T> struct TypeToInt {};
template <int T> struct IntToType {};

#define INIT(i, t) \
    template <> struct TypeToInt<t> { constexpr static int value = i; }; \
    template <> struct IntToType<i> { using type = t; };

INIT(42,float);
INIT(-17,double);

int main() {
    const int a = TypeToInt<float>::value;
    static_assert(a==42);
    IntToType<-17>::type pi;
    static_assert(std::is_same<double,decltype(pi)>::value);
    return 0;
}
Woodford
  • 3,746
  • 1
  • 15
  • 29