简体   繁体   English

“ uint32_t”的“ long unsigned int”模棱两可的调用

[英]Ambiguous Call of “long unsigned int” for “uint32_t”

I have a bunch of functions overloaded for all of the [u]int{8|16|32|64}_t types: 对于所有[u]int{8|16|32|64}_t类型,我都有很多函数重载:

std::string f( uint8_t) { /*something*/ }
std::string f(  int8_t) { /*something*/ }
std::string f(uint16_t) { /*something*/ }
std::string f( int16_t) { /*something*/ }
std::string f(uint32_t) { /*something*/ }
std::string f( int32_t) { /*something*/ }
std::string f(uint64_t) { /*something*/ }
std::string f( int64_t) { /*something*/ }
//A few more overloads with a few more types (bool, float, const char*, etc.)

I now call the function name with an argument of type long unsigned int : 我现在使用long unsigned int类型的参数调用函数名称:

template <typename type_blah> class Something { public:
        //...
        std::string call_f(void) const {
            return f(*((type_blah*)(internal_variable)));
        }
        //...
};

This produces an error: 这会产生一个错误:

error: call of overloaded 'f(long unsigned int&)' is ambiguous 错误:重载的'f(long unsigned int&)'的调用不明确


This happens, I suppose, because unsigned int and uint32_t are different types. 我想会发生这种情况,因为unsigned intuint32_t是不同的类型。 But, I can't overload the function more for long unsigned int because this is a redundant definition. 但是,对于long unsigned int ,我无法再重载该函数,因为这是一个冗余定义。 Ie: 即:

std::string f(long unsigned int) { /*something*/ }

. . . produces: 产生:

error: 'std::string f(uint32_t)' previously defined here 错误:先前在此处定义的“ std :: string f(uint32_t)”


It seems the type mechanisms are working against each other: it can't figure out which conversion to use because each conversion is equally valid, but a no-conversion overload can't be defined because it already has been. 看来类型机制正在互相作用:由于每次转换都同样有效,它无法弄清楚要使用哪个转换,但是由于已经定义了无转换重载,因此无法定义。

I can't cast the argument for various reasons. 由于种种原因,我无法提出论点。 Is there a way out of this? 有没有解决的办法?

Platform is g++ MinGW x86 running on Windows 7 x86-64. 平台是在Windows 7 x86-64上运行的g ++ MinGW x86。

What platform are you using? 您正在使用什么平台?

On Windows (Visual Studio 2010), unsigned long int is a distinct type from the others you mentioned. 在Windows(Visual Studio 2010)上, unsigned long int是与您提到的其他类型不同的类型。

Adding an overload specifically for that type resolved the error. 专门为此类型添加重载即可解决该错误。 This answer (and/or Google) may shed more light on the issue: Type of unsigned long is different from uint32_t and uint64_t on Windows (VS2010) . 这个答案(和/或Google)可能会更清楚地说明此问题: unsigned long的类型与Windows(VS2010)上的uint32_t和uint64_t不同

I defined an overload for unsigned long int like so: 我为unsigned long int定义了一个重载,如下所示:

std::string f( unsigned long int val )
{
  // Check that we chose the correct corresponding type
  // (This may vary by platform!)
  assert( sizeof( unsigned long int ) == sizeof( uint32_t ) );

  return f( static_cast<uint32_t>( val ) );
}

...tested in Visual Studio 2010 like so: ...在Visual Studio 2010中进行了如下测试:

void main()
{
  std::cout << "sizeof( unsigned long int ): " << sizeof( unsigned long int ) << std::endl;
  std::cout << "sizeof( uint32_t ): "          << sizeof( uint32_t )          << std::endl;

  unsigned long int x = 1u;
  std::cout << f( x ) << std::endl;
}

...and got the expected result: ...并获得了预期的结果:

sizeof( unsigned long int ): 4
sizeof( uint32_t ): 4
uint32_t

The following is my "test" based on the code provided above: 以下是基于上面提供的代码的“测试”:

#include <string>
#include <cstdint>
#include <iostream>

std::string f( uint8_t) { return "ui8";}
std::string f(  int8_t) { return "i8";}
std::string f(uint16_t) { return "ui16";}
std::string f( int16_t) { return "i16";}
std::string f(uint32_t) { return "ui32";}
std::string f(unsigned long long int) { return "unsigned long long";}
std::string f(unsigned long int) { return "unsigned long";}
std::string f( int32_t) { return "i32";}
//std::string f(uint64_t) { return "ui64";}
std::string f( int64_t) { return "i64";}

int main()
{
    unsigned long x = 42;
    unsigned y = 17;
    uint32_t z = 9;
    uint64_t w = 135;
    std::cout << "x: "<< f(x) << " y: " << f(y) << " z: " << f(z) << " w: " << f(w) << std::endl;
}

Sample output: 样本输出:

$ clang++ ambig.cpp -std=c++0x -Wall -m64
$ ./a.out 
x: unsigned long y: ui32 z: ui32 w: unsigned long
$ clang++ ambig.cpp -std=c++0x -Wall -m32
$ ./a.out 
x: unsigned long y: ui32 z: ui32 w: unsigned long long

(I copied my run with clang++, but the results are the same for g++) (我用clang ++复制了运行,但g ++的结果相同)

This makes sure that both the unsigned long and unsigned long long types are covered. 这样可以确保同时覆盖unsigned longunsigned long long类型。 Unfortunately, one of those is uint64_t , so it has to be removed. 不幸的是,其中之一是uint64_t ,因此必须将其删除。

If you do declare variables as unsigned long , you must supply a function that takes exactly that - and relying on it being equivalent to uint32_t is probably incorrect - even if they are the same bitsize. 如果确实将变量声明为unsigned long ,则必须提供一个准确地接受该变量的函数-并且依赖于它等同于uint32_t可能是不正确的-即使它们的位大小相同。

Since you're defining overloads for (nearly?) every type, perhaps your function should be a template instead? 由于您正在为(几乎?)每种类型定义重载,也许您的函数应该是模板?

template < typename T >
std::string f( T )
{
  /*something*/
}

If there is one set of code that works for all - or even most - types, that would save you a lot of work as well. 如果有一套适用于所有(甚至大多数)类型的代码,那也可以节省很多工作。

If for some reason you still need to force the call with the unsigned long int value to treat it as some other type (like uint32_t ), you could specify the template instantiation at the call-site: 如果由于某种原因您仍然需要强制使用unsigned long int值的调用将其视为其他类型(例如uint32_t ),则可以在调用站点指定模板实例化:

return f<uint32_t>( *internal_variable );

暂无
暂无

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

相关问题 一个使用uint32_t代替unsigned int的实际示例 - A practical example using uint32_t instead of unsigned int 如何区分unsigned int和uint32_t - How to distinguish unsigned int from uint32_t 从“const char*”到“uint32_t {aka unsigned int}”的无效转换[-fpermissive] - invalid conversion from ‘const char*’ to ‘uint32_t {aka unsigned int}’ [-fpermissive] 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 无符号长的类型与Windows上的uint32_t和uint64_t不同(VS2010) - Type of unsigned long is different from uint32_t and uint64_t on Windows (VS2010) 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} 从int16_t转换为uint32_t - Conversion from int16_t to uint32_t C++ 将 long、short 和所有整数转换为 uint32_t、int32_t 等是否有帮助? - C++ Does converting long, short and all ints to uint32_t, int32_t and so forth help at all? 如何安全地将 uint32_t 中的有符号字段提取为有符号数(int 或 uint32_t) - How to safely extract a signed field from a uint32_t into a signed number (int or uint32_t) 什么是 uint_fast32_t,为什么要使用它而不是常规的 int 和 uint32_t? - What is uint_fast32_t and why should it be used instead of the regular int and uint32_t?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM