1

Edit: highlighting the actual question with more context available if desired.

I want to implement the following method:

template <typename T>
<unspecified> type_identification();

For a generic type T, it must return a (relatively) unique identification that is stable over multiple invocations of the same program and may be used for inter-process communication (so no pointer-based solutions).

Compiler-specific macros/extensions/intrinsics may be used, preferably available for both MSVC and clang.

I have considered std::type_info::hash_code, or std::type_info::name but both of those cannot guarantee the same output over multiple invocations of the same program.


Trying to avoid the XY-problem by immediately explaining the problem I am trying to solve.

I have written code to generically store data on file for later use. Each so-called entry in the file is assigned a label by the application code that it must use to access the same entry in a later program invocation. The API basically boils down to:

template <typename T>
void make(const std::string &name, T value);

template <typename T>
T get(const std::string &name);

Note that this is merely example code.

When application code accesses a value through get<T>, it explicitly specifies the type of the entry so that the implementation may use reinterpret_cast to give access to the entry as the actual type instead of as a void *.

Let's assume for the sake of this question that all dangers and pitfalls concerning reinterpret_cast and persisting data to file have been taken into account.

To avoid nasty crashes because application code has messed up the template argument, I would like to add some type identification to each entry in the file. Basically, when the application code does something like:

make("integer", 5);
auto a = get<std::string>("integer");

I would like to throw an exception indicating the mismatch in actual type and requested type.

Maarten Bamelis
  • 2,243
  • 19
  • 32
  • 4
    Are you trying to invent JSON? – SergeyA Aug 13 '18 at 17:07
  • 1
    "I have considered using: [stuff]" - why not just use a string? –  Aug 13 '18 at 17:11
  • @SergeyA Not trying to invent JSON. This really is the problem I am trying to solve. – Maarten Bamelis Aug 13 '18 at 17:34
  • @NeilButterworth Can you show in an answer how the templated `make` would be implemented then? If it is similar to R Sahu's answer, please read my comment there. – Maarten Bamelis Aug 13 '18 at 17:35
  • 1
    Perhaps use https://stackoverflow.com/questions/81870/is-it-possible-to-print-a-variables-type-in-standard-c and save a string. – Tim Randall Aug 13 '18 at 17:39
  • @TimRandall I haven't considered using compiler-specific macros but it is a very interesting approach. I have edited the question (hopefully making it more clear and focused) to also include compiler-specific macros/extensions/intrinsics. – Maarten Bamelis Aug 13 '18 at 17:57

1 Answers1

2

You can add code to define the persistent names of the types you wish to persist.

template <typename T> struct persistent_type;

template <> struct persistent_type<int>
{
   static std::string_view name() { return "int"; }
}

template <> struct persistent_type<double>
{
   static std::string_view name() { return "double"; }
}

etc.

And use them in make

template <typename T>
void make(std::string_view name, T value)
{
   // Save the type name of the data, persistent_type<T>::name()

   // Save the name of the data, name

   // Save the data, value
}

When getting the value, use

template <typename T>
T get(std::string_view name)
{
   // Read the type name and make sure it is equal to persistent_type<T>::name().

   // Rest of your logic to read the object
}
Deduplicator
  • 44,692
  • 7
  • 66
  • 118
R Sahu
  • 204,454
  • 14
  • 159
  • 270
  • This could work for me if only you could implement the `persistent_type` template and not use specializations for each persisted type. That kind of manual labour is a viable last resort but I'd like to avoid it if possible (hence asking SO for advice). – Maarten Bamelis Aug 13 '18 at 17:32
  • @MaartenBamelis, that's fair. However, I would argue that the number of types that you wish to persist is unlikely to grow out of control and, hence, the burden of implementing specializations of `persistent_type` won't be bad. – R Sahu Aug 13 '18 at 17:37