无法在std::tuple中存储std::type_info对象的解决方法
问题原因
std::type_info是不可拷贝、不可移动的类型——它没有公开的拷贝构造函数和赋值运算符,因此无法直接将其作为std::tuple的元素类型,也不能通过std::make_tuple完成拷贝初始化。
解决方案
有两种常用方式实现存储类型信息的需求:
1. 使用std::reference_wrapper存储引用
typeid返回的是全局的std::type_info实例,其生命周期与程序一致,存储引用是安全的。修改后的代码如下:
#include <iostream> #include <string> #include <tuple> #include <typeinfo> #include <any> #include <functional> // 包含std::reference_wrapper int main() { // 将tuple第一个元素类型改为std::reference_wrapper<const std::type_info> std::tuple<std::reference_wrapper<const std::type_info>, int, std::any> tpl = std::make_tuple(std::cref(typeid(float)), 1, "Hello"); const auto&[type_ref, num, anyval] = tpl; // 通过get()获取底层的std::type_info引用 std::cout << type_ref.get().name() << std::endl; std::cout << num << std::endl; std::cout << std::any_cast<const char*>(anyval) << std::endl; return 0; }
这里用std::cref创建常量引用的包装器,确保引用的typeid(float)返回对象不会被修改。
2. 使用const std::type_info*存储指针
直接存储std::type_info的指针同样可行,依赖typeid返回对象的全局生命周期:
#include <iostream> #include <string> #include <tuple> #include <typeinfo> #include <any> int main() { std::tuple<const std::type_info*, int, std::any> tpl = std::make_tuple(&typeid(float), 1, "Hello"); const auto&[type_ptr, num, anyval] = tpl; std::cout << type_ptr->name() << std::endl; std::cout << num << std::endl; std::cout << std::any_cast<const char*>(anyval) << std::endl; return 0; }
这种方式代码更简洁,无需额外引入<functional>头文件。
注意事项
std::type_info::name()返回的字符串格式由编译器定义,不同编译器(如GCC、MSVC)返回结果可能不同,不要依赖其格式做解析。- 无论用引用还是指针,都无需担心
typeid返回对象的生命周期问题——它们都是全局实例,与程序同生命周期。
内容的提问来源于stack exchange,提问作者Aayush Anand
相关产品推荐
相关产品推荐

