问题
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.
回答1:
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