问题描述
您可能不得不原谅我,因为我是 C++ 新手,并且可能在我迄今为止编写的代码中犯了一些基本错误。
static tuple<read_result,uint8_t*> m_scan_record(bool skip,uint32_t& size,FILE* file)
{
read_result result;
tuple<read_result,uint32_t*> rd_rec_size_result = m_read_generic_t<uint32_t>(file);
result = (read_result)get<0>(rd_rec_size_result);
if (result != read_success )
{
return tuple<read_result,uint8_t*>(result,nullptr);
}
size = (uint32_t) get<1>(rd_rec_size_result);
if ( skip )
{
fseek(file,size,SEEK_CUR);
}
// ...
}
template<typename T>
static tuple<read_result,T*> m_read_generic_t(FILE* file)
{
T ret = 0;
read_result result = m_read_from_file_to_buffer(&ret,sizeof(T),file);
if (result == read_success)
{
return tuple<read_result,T*>(result,&ret);
}
return tuple<read_result,nullptr);
}
cast from ‘std::__tuple_element_t<1,std::tuple<read_result,unsigned int*> >’ {aka ‘unsigned int*’} to ‘uint32_t’ {aka ‘unsigned int’} loses precision [-fpermissive]
我的意图以及我应该做什么/发生什么:
-
在
m_scan_record
的声明中,size
参数是用&
声明的,它旨在允许我通过引用传递值,类似于使用 { {1}} c# 关键字 -
我调用了泛型(模板)函数
REF
,该函数以指定的类型m_read_generic_t
调用,因此(根据其定义)将返回类型为 {{1} } -
一旦我得到了
<unit32_t>
返回的元组,我想取元组的第二个值指向的tuple<read_result,uint32_t*>
值,并将该值放入 {{1}上面第 1 点提到的变量,然后调用函数可能会在堆栈上进一步访问该变量。 -
从以上几点你可以看出我的意图(我很感激我可能离现实很远!)就是在这一行:
size = (uint32_t) get(rd_rec_size_result);
我所做的只是获取一个“指向”值并将其放入匹配类型的变量中,就像经常引用的教科书示例一样:
m_read_generic_t
很明显,这不是我的代码真正发生的事情,因为如果是这样,我认为不需要演员表。但是如果我删除它,就像这样:
unit32_t
size
因此,我相信我做错了什么 - 但我不知道是什么。这与我从元组中取出指针的方式有关吗?或者在从 uint32_t* 获取 uint32_t 值时还有其他事情发生吗?
这一切都在 Ubuntu 20.04、FWIW 上的 C++ 环境中
非常感谢您的任何/所有建议;请放轻松!
解决方法
tuple<read_result,uint32_t*> rd_rec_size_result = ...
这个元组的第二个成员,正如这里明确声明的,是一个指向 uint32_t
的指针。这就是 uint32_t *
在 C++ 中的意思。
size = (uint32_t) get<1>(rd_rec_size_result);
这会检索 uint32_t *
并尝试将其转换为 uint32_t
。 C++ 不能以这种方式工作。尽管可以强制进行这种转换,但您的编译器完全有权利相信无论此代码试图做什么,它都一定是错误的。
也许我最初想知道,您的意图是取消引用指针。无论如何,这就是编译错误的原因。如果您的意图是真正取消引用此指针,那么只需将其更改为
size = *get<1>(rd_rec_size_result);
然而,这不会是你麻烦的结束。即使在修复了这个编译错误之后,这样显示的代码仍然会很糟糕,很糟糕。
这是因为 m_read_generic_t
返回一个指向本地对象的指针,该对象将在函数返回时被销毁,并且在此处尝试取消引用该指针将导致 demons fly out of your nose。
这里真正的修复是将m_read_generic_t
更改为不返回一个指针作为元组中的第二个值排在第一位,从而在第一时间消除编译错误。