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.
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
}
来源:https://stackoverflow.com/questions/51827285/persist-c-type-info-to-file-for-use-across-program-invocations