编辑:根据需要突出显示具有更多上下文的实际问题.
我要实现以下方法:
template <typename T>
<unspecified> type_identification();
对于通用类型T,它必须返回(相对)唯一的标识,该标识在同一程序的多次调用中稳定,并且可以用于进程间通信(因此,没有基于指针的解决方案).
可以使用特定于编译器的宏/扩展名/内部函数,最好可同时用于MSVC和clang.
我已经考虑过std :: type_info :: hash_code或std :: type_info :: name,但是它们都不能保证通过同一程序的多次调用获得相同的输出.
试图通过立即解释我要解决的问题来避免XY-problem.
我编写了将代码一般存储在文件中以供以后使用的代码.文件中的每个所谓条目都由应用程序代码分配了一个标签,在以后的程序调用中,该代码必须用于访问同一条目.该API基本上可以归结为:
template <typename T>
void make(const std::string &name, T value);
template <typename T>
T get(const std::string &name);
请注意,这仅仅是示例代码.
当应用程序代码通过get< T>访问值时,它显式指定条目的类型,以便实现可以使用reinterpret_cast将访问权限作为实际类型而不是void *.
为了这个问题,让我们假设已经考虑了所有与reinterpret_cast和将数据持久保存到文件中有关的危险和陷阱.
为了避免由于应用程序代码弄乱了模版参数而导致的严重崩溃,我想向文件中的每个条目添加一些类型标识.基本上,当应用程序代码执行以下操作时:
make("integer", 5);
auto a = get<std::string>("integer");
我想抛出一个异常,指示实际类型和请求的类型不匹配.
解决方法:
您可以添加代码来定义要保留的类型的永久名称.
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"; }
}
等等
并在制造中使用它们
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
}
获得价值时,请使用
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
}