我想编写模板函数,当类型为整数时应调用该函数,例如int8,int16,int32,int64,uint8,uint16,uint32,uint64;还有一个仅用于FLOAT类型float32,float64的具有不同代码的其他模板函数(相同名称)...是否可以在C ++中使用模板函数来完成它?例如:
template <class T>
void fun(T b)
{
/// Code for integer type
}
template <class S>
void fun(S a)
{
/// Code for floating type
}
是的,这是可能的。一种方法是使用SFINAE:
template <class T, std::enable_if_t<std::is_integral_v<T>, int> = 0>
void fun(T b)
{
/// Code for integer type
}
template <class S, std::enable_if_t<std::is_floating_point_v<T>, int> = 0>
void fun(S a)
{
/// Code for floating type
}
请注意,enable_if
的2个条件必须是不相交的,我们可以从enable_if
和std::is_integral
的文档中看出它们是。如果不是,则条件必须看起来像std::is_integral
。
[这里发生的是,如果不满足条件,std::is_floating_point
将使重载之一“无法编译”,这意味着由于SFINAE根本不考虑重载。
如果使用的是C ++ 17,则可能要考虑使用std::is_floating_point
:
std::is_integral_v<T> && !std::is_floating_point_v<T>
根据您的全部意图,在std::enable_if_t
和if constexpr
之外,您也可以使用常规函数重载和/或模板专门化:
template <class T>
void fun(T b)
{
if constexpr (std::is_integral_v<T>) {
/// Code for integer type
} else if constexpr (std::is_floating_point_v<T>) {
/// Code for floating type
}
}
希望有所帮助。
根据SFINAE,我们可以为一种类型设计编译错误,而让另一种进入模板替换阶段。对于整数类型与浮点类型,我们可以将位相关的运算符用于整数,例如std::enable_if。例如,
#include <iostream>
#include <cstdint>
template < typename T >
void fun(T b)
{
std::cout << "Generic called: " << b << std::endl;
}
void fun(int16_t b)
{
std::cout << "int16_t: " << b << std::endl;
}
void fun(int32_t b)
{
std::cout << "int32_t: " << b << std::endl;
}
void fun(float b)
{
std::cout << "float: " << b << std::endl;
}
template <>
void fun<int64_t>(int64_t b)
{
std::cout << "int64_t specialization: " << b << std::endl;
}
int main(int argc, char** argv)
{
double dbl = 3.14159;
float flt = 1.12345;
int16_t i16 = 16;
int32_t i32 = 32;
fun(dbl);
fun(flt);
fun(i16);
fun(i32);
fun(5.555f);
fun(32);
fun(std::numeric_limits<int64_t>::max());
return 0;
}
给予
SFINAE