我为所有[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.)
我现在使用long unsigned int
类型的参数调用函数名称:
template <typename type_blah> class Something { public:
//...
std::string call_f(void) const {
return f(*((type_blah*)(internal_variable)));
}
//...
};
这会产生错误:
错误:调用重载'f(long unsigned int&amp;)'是不明确的
我想这会发生,因为unsigned int
和uint32_t
是不同的类型。但是,我不能为long unsigned int
重载函数,因为这是一个冗余的定义。即:
std::string f(long unsigned int) { /*something*/ }
。 。 。生产:
错误:'std :: string f(uint32_t)'先前在这里定义
似乎类型机制相互作用:它无法确定要使用哪种转换,因为每次转换同样有效,但无法定义无转换过载,因为它已经存在。
我不能出于各种原因抛出论点。有没有办法解决这个问题?
平台是在Windows 7 x86-64上运行的g ++ MinGW x86。
答案 0 :(得分:1)
您使用的是什么平台?
在Windows(Visual Studio 2010)上,unsigned long int
与您提及的其他类型不同。
专门为该类型添加重载解决了错误。这个答案(和/或谷歌)可能会对这个问题有所了解:Type of unsigned long is different from uint32_t and uint64_t on Windows (VS2010)。
我为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 ) );
}
...在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;
}
......并得到了预期的结果:
sizeof( unsigned long int ): 4
sizeof( uint32_t ): 4
uint32_t
答案 1 :(得分:0)
以下是基于上面提供的代码的“测试”:
#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;
}
示例输出:
$ 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
(我用clang ++复制了我的运行,但g ++的结果是相同的)
这可确保涵盖unsigned long
和unsigned long long
类型。不幸的是,其中一个是uint64_t
,因此必须将其删除。
如果确实将变量声明为unsigned long
,则必须提供一个完全相同的函数 - 并且依赖它等同于uint32_t
可能是不正确的 - 即使它们是相同的bitsize。
答案 2 :(得分:0)
既然您为每种类型(几乎?)定义了重载,那么您的函数应该是模板吗?
template < typename T >
std::string f( T )
{
/*something*/
}
如果有一组代码适用于所有类型 - 甚至大多数类型 - 那么这将为您节省大量工作。
如果由于某种原因你还需要强制使用unsigned long int
值的呼叫将其视为其他类型(如uint32_t
),则可以在呼叫站点指定模板实例化:
return f<uint32_t>( *internal_variable );