简体   繁体   English

C++ 从 'std::__tuple... {aka 'unsigned int*'} 转换为 'uint32_t' {aka 'unsigned int'} 失去精度

[英]C++ Cast from ‘std::__tuple… {aka ‘unsigned int*’} to ‘uint32_t’ {aka ‘unsigned int’} loses precision

You may have to forgive me as I'm new to C++ and may have made some fundamental errors with the code I have worked up so far.您可能不得不原谅我,因为我是 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, T*>(result, nullptr);
}

When I compile this code I am getting this error:当我编译这段代码时,我收到了这个错误:

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]

My intentions and what I am expected to do/happen:我的意图和我应该做/发生的事情:

  1. In the declaration of m_scan_record , the size argument is declared with a & which is intended to allow me to pass the value by reference, analogous to using the REF c# keywordm_scan_record的声明中,使用&声明size参数,旨在允许我通过引用传递值,类似于使用REF c# 关键字

  2. I make a call to generic (template) function m_read_generic_t which is called with the specified type <unit32_t> and therefore (according to its definition) will return a type of tuple<read_result, uint32_t*>我调用了通用(模板)function m_read_generic_t ,它使用指定的类型<unit32_t>调用,因此(根据其定义)将返回一种类型tuple<read_result, uint32_t*>

  3. Once I have the tuple returned by m_read_generic_t , I want to take the unit32_t value pointed to by the second value of the tuple, and put that value into the size variable mentioned at point 1, above, which presumably will then be accessible to the calling function one step further up the stack.一旦我得到m_read_generic_t返回的元组,我想获取元组的第二个值指向的unit32_t值,并将该值放入上面第 1 点提到的size变量中,然后调用可能可以访问该变量function 再往上一步。

  4. From the above points you can hopefully see that my intention (and I appreciate that I may be far away in reality:) is that at this line:从以上几点你可以希望看到我的意图(我很感激我在现实中可能很遥远:)是在这一行:

    size = (uint32_t) get<1>(rd_rec_size_result);大小 = (uint32_t) 获取<1>(rd_rec_size_result);

all I am doing is simply grabbing a 'pointed to' value and putting it into a variable of a matching type, much like the oft-cited textbook example:我所做的只是获取一个“指向”值并将其放入匹配类型的变量中,就像经常引用的教科书示例一样:

uint32_t v = 123;
uint32_t* ptr_to_v = &v;
uint32_t x = ptr_to_v;   // x == 123

Clearly this is not what is really going on with my code, though, because if it were, I presume that the cast would be un-needed.显然,这不是我的代码真正发生的事情,因为如果是这样,我认为演员将是不需要的。 But if I remove it, like this:但如果我删除它,像这样:

size = get<1>(rd_rec_size_result);

then I get a compile-time error:然后我得到一个编译时错误:

a value of type "std::__tuple_element_t<1UL, std::tuple<read_result, uint32_t *>>" cannot be assigned to an entity of type "uint32_t"

I believe therefore that I am doing something badly wrong - but I can't work out what.因此,我相信我做错了什么——但我不知道是什么。 Is this to do with the way I am taking the pointer out of the tuple;这与我将指针从元组中取出的方式有关吗? or is there something else going on when it comes to the getting a uint32_t value from a uint32_t*?或者在从 uint32_t* 获取 uint32_t 值时还有其他事情发生吗?

This is all in a C++ environment on Ubuntu 20.04, FWIW这一切都在 Ubuntu 20.04 上的 C++ 环境中,FWIW

Many thanks in advance for any/all suggestions;非常感谢您的任何/所有建议; please go easy on me!请 go 对我放心!

tuple<read_result, uint32_t*> rd_rec_size_result = ...

The 2nd member of this tuple, as explicitly declared here, is a pointer to a uint32_t .这个元组的第二个成员,正如这里明确声明的,是一个指向uint32_t的指针。 That's what uint32_t * means, in C++.这就是uint32_t *的含义,在 C++ 中。

size = (uint32_t) get<1>(rd_rec_size_result);

This retrieves the uint32_t * and attempts to convert it to a uint32_t .这将检索uint32_t *并尝试将其转换为uint32_t C++ does not work this way. C++ 不能这样工作。 Although this conversion can be forced your compiler has every right to believe that whatever this code is trying to do it must be wrong.尽管可以强制进行这种转换,但您的编译器完全有权利相信无论这段代码试图做什么,它一定是错误的。

Perhaps I was wondering initially, your intention was to dereference the pointer.也许我最初想知道,您的意图是取消引用指针。 This is the reason for your compilation error, in any case.无论如何,这就是您的编译错误的原因。 If your intention was to, truly, dereference this pointer, then this would've been a simple matter of changing this to如果您的意图是真正取消引用此指针,那么将其更改为

size = *get<1>(rd_rec_size_result);

However, that's not going to be the end of your troubles.然而,这不会是你麻烦的结束。 Even after this compilation error is fixed, this way, the shown code will still be badly, badly broken.即使修复了这个编译错误,这样,显示的代码仍然会被严重破坏。

This is because m_read_generic_t returns a pointer to a local object, which will get destroyed when the function returns, and attempting to dereference this pointer, here, will make demons fly out of your nose .这是因为m_read_generic_t返回一个指向本地 object 的指针,当 function 返回时,该指针将被破坏,并且在这里尝试取消引用该指针会使恶魔飞出你的鼻子

The real fix here is to change m_read_generic_t to not return a pointer as the 2nd value in the tuple in the first place, thus eliminating the compilation error in the first place.真正的解决方法是首先将m_read_generic_t更改为返回指针作为元组中的第二个值,从而首先消除编译错误。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 错误:从“uint8_t* {aka unsigned char*}”转换为“unsigned int”会丢失精度 [-fpermissive] - error: cast from ‘uint8_t* {aka unsigned char*}’ to ‘unsigned int’ loses precision [-fpermissive] 从“const char*”到“uint32_t {aka unsigned int}”的无效转换[-fpermissive] - invalid conversion from ‘const char*’ to ‘uint32_t {aka unsigned int}’ [-fpermissive] C ++:错误:无法转换&#39;ns3 :: TracedValue <ns3::SequenceNumber<unsigned int, int> &gt;&#39;到&#39;uint32_t {aka unsigned int} - c++: error: cannot convert ‘ns3::TracedValue<ns3::SequenceNumber<unsigned int, int> >’ to ‘uint32_t {aka unsigned int} 从&#39;BYTE * {aka unsigned char *}&#39;转换为&#39;DWORD {aka long unsigned int}&#39;会失去精度[-fpermissive] - cast from 'BYTE* {aka unsigned char*}' to 'DWORD {aka long unsigned int}' loses precision [-fpermissive] 如何区分unsigned int和uint32_t - How to distinguish unsigned int from uint32_t 如何解决隐式转换丢失整数精度:&#39;size_t&#39;(又名&#39;unsigned long&#39;)到&#39;int&#39;警告? - How to solve the Implicit conversion loses integer precision: 'size_t' (aka 'unsigned long') to 'int' warning? iOS-隐式转换将整数精度&#39;size_t&#39;(aka&#39;unsigned long&#39;)转换为&#39;int&#39; - iOS - implicit conversion loses integer precision 'size_t' (aka 'unsigned long') to 'int' “ uint32_t”的“ long unsigned int”模棱两可的调用 - Ambiguous Call of “long unsigned int” for “uint32_t” 一个使用uint32_t代替unsigned int的实际示例 - A practical example using uint32_t instead of unsigned int xcode 构建失败 隐式转换丢失 integer 精度:“size_t”(又名“unsigned long”)到“socklen_t”(又名“unsigned int”) - xcode build failing over Implicit conversion loses integer precision: 'size_t' (aka 'unsigned long') to 'socklen_t' (aka 'unsigned int')
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM