C++ 除了casting char之外,还有没有更好的方法来获取变量值*

C++ 除了casting char之外,还有没有更好的方法来获取变量值*,c++,c,C++,C,在我们的遗留代码中,我们尝试将原语值从char*转换为某些特定类型,如int、float、double、char(一堆char)等 代码如下所示 char *data = db_data(process, retry_column); int retry_time = *(int*)(data); //...... data = db_data(process, user_name_column); std::string user_name(data, std::strlen(data));

在我们的遗留代码中,我们尝试将原语值从char*转换为某些特定类型,如int、float、double、char(一堆char)等

代码如下所示

char *data = db_data(process, retry_column);
int retry_time = *(int*)(data);
//......
data = db_data(process, user_name_column);
std::string user_name(data, std::strlen(data));
有没有更好的方法可以在不重新设计库的情况下获得变量数据类型


如果唯一的方法是重新设计库,在不考虑性能和类型安全的情况下(我想同时实现两者),您会建议什么样的解决方案,boost::variant能否完成任务?

显而易见的解决方案是
boost::variant


即使如此,给
retry\u column
类型
int\u column\u t
也可能有用,以便使用
int db\u数据(…,int\u column\u t)
重载

存在一个固有的问题,即无法知道返回的字节是否确实是正确的类型。它们只是0和1的流。因此,无法确保数据库中的数据是正确的类型(不考虑数据大小)。也就是说,通过在数据类型上模板化db_数据,可以避免客户机代码中的强制转换。然后,它可以验证大小是否正确,然后将数据转换为正确的类型。这将如下所示:

template<class DataType> DataType db_data();
模板数据类型db_data();

如果你想拥有类型安全性,毫无疑问,你应该选择
boost::variant

但是,这需要重新设计db_data(),因为返回的不再是char*

因此,如果有太多的事情要做,并且您希望从一个较轻的更改开始,我可以为您推荐以下模板和字符串案例的专业化:

template <typename T> 
inline T vdata(char* val) 
   { return *reinterpret_cast<T*>(val); }     

template<>
inline string vdata(char* val) 
   { return string(val); }  // special case for strings 
当然,您可以通过以下方式避免使用临时数据来简化:

模板 inline T vdb_data(int proc,char*col)//注意:使用与原始文件相同的参数签名,我不知道您使用的真正类型 {返回vdata(db_数据(proc,col));}


但正如一些人指出的,这个解决方案很好,但不会给您类型安全性。例如,在字符串版本中,至少要进行一些一致性检查(例如,它是空的终止,并且长度适合于STR::Max(sixx)())/P>C或C++。答案会有很大的不同。如果可能的话,你应该避免删除字体。为什么不通过引用传递要设置的对象(在第一次调用中是
int&
,在第二次调用中是
std::string&
)-这意味着每个类型有一个重载,它更有意义并且是类型安全的。此代码不合法,
数据
的地址可能未按
int
要求对齐。您的代码还存在潜在的别名和对齐问题。<代码>数据<代码>中的地址可能无法正确地被代码< INT> INT/COM>对齐,即使它被正确对齐,通过一个类型<代码> int 的GLUVE访问一组 char < /C> >的存储值是UB,因为它违反了严格的别名。@ MatthiasB C++,这些都是遗留的c代码库,我计划将其正确包装,如果我不需要重新设计它就好了(需要清理的东西太多了)要对其进行模板化并进行审查,您可以使db_数据的模板化版本调用旧版本,以避免重新设计并保持向后兼容性。
int retry_time = vdata<int>(data);
... 
std::string user_name = vdata<string>(data);