我希望有一组函数可以接受任何uintX_t
变体,而无需复制/粘贴大量代码。到目前为止,我正在尝试使用“标记”来确定要调用的函数。出于显而易见的原因,T = unsigned
不起作用,因为我可能有uint32_t
,uint16_t
等。
struct number_tag {};
struct hexadecimal : number_tag {};
struct number : number_tag {};
template <typename T = unsigned, typename Tag>
void write(T t);
然后在.cpp文件中:
template <>
void write<unsigned, hexadecimal>(unsigned num)
{
}
template <>
void write<unsigned, number>(unsigned num)
{
}
理想情况下,我想这样称呼它:
write<number>(10);
write("\n");
write<hexadecimal>(0xFF);
如何编写此代码,以便我不必write<unsigned, number>
为每个uintX_t
变体创建一系列特化?
答案 0 :(得分:3)
你不能部分专门化功能(boo),但你可以使用更多无用的结构!
struct number_tag {};
struct hexadecimal : number_tag {};
struct number : number_tag {};
template <typename Tag, typename T = unsigned>
struct Writer;
template <typename T>
struct Writer<hexadecimal, T>
{
static void write(T num) {}
};
template <typename T>
struct Writer<number, T>
{
static void write(T num) {}
};
template <typename Tag, typename T = unsigned>
void write(T t)
{
Writer<Tag, T>::write(t);
}
int main()
{
write<number>(10);
write<hexadecimal>(0xFF);
}
答案 1 :(得分:1)
如果你想根据write
使用单独的tag
专门化,那么添加重载(因为函数不能部分专门化):
template <typename T = unsigned>
void write(T t, hexadecimal tag)
{
}
template <typename T = unsigned>
void write(T t, number tag)
{
}
template <typename Tag, typename U = unsigned>
void write(U num)
{
write<U>(num, Tag{});
}
write<number>(10);
write<hexadecimal>(0xFF);
write<number, std::uint16_t>(0xFF);
如果您想为您的函数添加约束以使其仅接受无符号整数类型,则以下代码会进行正确的验证:
template <typename Tag, typename U = unsigned>
auto write(U num) -> typename std::enable_if<std::is_unsigned<U>::value, void>::type
{
write<U>(num, Tag{});
}
write<number>(10u);
//write<number>(-1); // triggers error
注意:您当前的声明template <typename T = unsigned> void write(T t);
不强制类型为unsigned
,因为参数的类型是由基于实际参数类型的编译器。
如果您想强制传递给write
函数的任何类型为unsigned
,您可以使用以下代码:
template <typename Tag, typename U>
void write(U num)
{
write<typename std::make_unsigned<U>::type>(num, Tag{});
}
write<number>(-1); // gets converted to unsigned type