注意:我在`msg(long)` 和候选 `msg(int32_t)` 和 `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++ 接口类,它有像这样的构造函数
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
样式类型替换这个界面——如果可以的话,我不需要问这个问题;)
问题是如何obj_from_
根据整数类型的位数调用正确的函数。
建议的解决方案
我提出了两个建议的解决方案,因为没有杀手解决方案浮现在列表的顶部,并且有一些被破坏了。
解决方案 1
由Cheers 和 hth 提供。- 阿尔夫。从这一点开始的评论是我自己的 - 随时评论和/或编辑。
优点
- 相当简单(至少与 相比boost::enable_if
) - 不依赖 3rd 方库(只要编译器支持tr1
)
*缺点** - 如果需要更多功能(如anotherObj_from_int32
等),则需要更多代码
这个解决方案可以在下面找到 - 看看,它很漂亮!
解决方案 2
好处
函数完成后,添加需要转换的
ConvertFromIntegral
新函数是微不足道的 - 只需编写一组重载 onint32_t
和int64_t
无符号等价物。仅将模板的使用保留在一个地方,它们不会随着技术的重复使用而传播。
缺点
- 可能过于复杂,使用
boost::enable_if
. 仅在一次出现的事实中有所缓解。
由于这是我自己的,我不能接受它,但如果你认为它很整洁,你可以投票赞成(显然有些人根本不认为它很整洁,这就是反对它的原因,我想!)感谢所有谁贡献了想法!
该解决方案涉及从int
、到long
和的转换函数(对于无符号版本也类似)。这与另一组在 上重载的函数和无符号等效函数相结合。这两个函数可以组合,但是第一个转换函数构成了一个方便的实用程序集,可以重用,然后第二个函数集非常简单。long long
int32_t
int64_t
int32_t
int64_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
!)版本在“msg(long)”等函数的模糊重载与候选“msg(int32_t)”和“msg(int64_t)”中给出