gpt4 book ai didi

c++ - 在编译时确定整数类型的位数

转载 作者:可可西里 更新时间:2023-11-01 18:29:43 24 4
gpt4 key购买 nike

注意:我在 Ambiguous overload of functions like `msg(long)` with candidates `msg(int32_t)` and `msg(int64_t)` 添加了一个类似但大大简化的问题版本.该版本的优点是在单个文件中包含完整的可编译示例。

问题

我有一个 C 库,函数如下

obj_from_int32(int32_t& i);
obj_from_int64(int64_t& i);
obj_from_uint32(uint32_t& i);
obj_from_uint64(uint64_t& i);

在这种情况下,类型 int32_t不是 std 类型 - 它们是实现定义的,在这种情况下是一个字符数组 (在下面的示例中,我省略了转换 - 它不会改变关于根据整数类型中的位数将整数类型映射到特定函数的问题。

我有第二个 C++ 接口(interface)类,它有像这样的构造函数

MyClass(int z);
MyClass(long z);
MyClass(long long z);
MyClass(unsigned int z);
MyClass(unsigned long z);
MyClass(unsigned long long z);

请注意,我不能用 std::int32_t 样式类型替换此接口(interface) - 如果可以的话我就不需要问这个问题了;)

问题是如何根据整数类型的位数调用正确的obj_from_ 函数。

建议的解决方案

我提出了两个建议的解决方案,因为没有 killer 解决方案浮到列表的顶部,并且有一些被破坏了。

方案一

Cheers and hth. - Alf 提供.从这一点开始的评论是我自己的 - 请随意评论和/或编辑。

优点 - 相当简单(至少与 boost::enable_if 相比) - 不依赖第 3 方库(只要编译器支持 tr1)

*缺点** - 如果需要更多功能(如 anotherObj_from_int32 等),则需要更多代码

这个解决方案可以在下面找到 - 看看,它很漂亮!

方案二

优势

  • ConvertFromIntegral 函数完成后,添加需要转换的新函数就很简单了 - 只需编写一个在 int32_tint64_t< 上重载的集合 和未签名的等价物。

  • 只在一个地方使用模板,它们不会随着技术的重复使用而传播。

缺点

  • 可能过于复杂,使用 boost::enable_if。由于这只出现在一个地方,这在一定程度上缓解了这一点。

因为这是我自己的,所以我不能接受它,但是如果你认为它很整洁,你可以给它投赞成票(显然有些人认为它根本不整洁,这就是反对它的原因因为,我想!)感谢所有提供想法的人!

方案涉及到intlonglong longint32_t的转换函数int64_t (对于未签名的版本也类似)。这与在 int32_tint64_t 和无符号等价物上重载的另一组函数相结合。这两个函数可以组合,但第一个转换函数构成了一个方便的实用程序集,可以重复使用,第二个函数集非常简单。

// Utility conversion functions (reuse wherever needed)
template <class InputT>
typename boost::enable_if_c<sizeof(InputT)==sizeof(int32_t) && boost::is_signed<InputT>::value,
int32_t>::type ConvertFromIntegral(InputT z) { return static_cast<int32_t>(z); }

template <class InputT>
typename boost::enable_if_c<sizeof(InputT)==sizeof(int64_t) && boost::is_signed<InputT>::value,
int64_t>::type ConvertFromIntegral(InputT z) { return static_cast<int64_t>(z); }

template <class InputT>
typename boost::enable_if_c<sizeof(InputT)==sizeof(uint32_t) && boost::is_unsigned<InputT>::value,
uint32_t>::type ConvertFromIntegral(InputT z) { return static_cast<uint32_t>(z); }

template <class InputT>
typename boost::enable_if_c<sizeof(InputT)==sizeof(uint64_t) && boost::is_unsigned<InputT>::value,
uint64_t>::type ConvertFromIntegral(InputT z) { return static_cast<uint64_t>(z); }

// Overload set (mock implementation, depends on required return type etc)
void* objFromInt32 (int32_t i) { obj_from_int32(i); }
void* objFromInt64 (int64_t& i) { obj_from_int64(i); }
void* objFromUInt32(uint32_t& i) { obj_from_uint32(i); }
void* objFromUInt64(uint64_t& i) { obj_from_uint64(i); }

// Interface Implementation
MyClass(int z) : _val(objFromInt(ConvertFromIntegral(z))) {}
MyClass(long z): _val(objFromInt(ConvertFromIntegral(z))) {}
MyClass(long long z): _val(objFromInt(ConvertFromIntegral(z))) {}
MyClass(unsigned int z): _val(objFromInt(ConvertFromIntegral(z))) {}
MyClass(unsigned long z): _val(objFromInt(ConvertFromIntegral(z))) {}
MyClass(unsigned long long z): _val(objFromInt(ConvertFromIntegral(z))) {}

解决方案的简化(单一可编译 .cpp!)版本在 Ambiguous overload of functions like `msg(long)` with candidates `msg(int32_t)` and `msg(int64_t)` 中给出。

最佳答案

给定第 3rd 方函数……

void obj_from_int32( int32_bytes_t& i );
void obj_from_int64( int64_bytes_t& i );
void obj_from_uint32( uint32_bytes_t& i );
void obj_from_uint64( uint64_bytes_t& i );

您可以为内置类型调用“正确的”此类函数,如下所示:

template< int nBytes, bool isSigned >
struct ThirdParty;

template<>
struct ThirdParty< 4, true >
{
template< class IntegralT >
static void func( IntegralT& v )
{ obj_from_int32( v ) } // Add whatever conversion is required.
};

// Etc., specializations of ThirdParty for unsigned and for 8 bytes.

template< class IntegralT >
void myFunc( IntegralT& v )
{ ThirdParty< sizeof( v ), std::is_signed< IntegralT >::value >::func( v ); }

关于c++ - 在编译时确定整数类型的位数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10578359/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com