我想写类型为整数时应该调用的模板函数,例如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
}
答案 0 :(得分:5)
是的,这是可能的。一种方法是使用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个条件必须是不相交的,我们可以从std::is_integral
和std::is_floating_point
的文档中看到它们。如果他们不是,那么条件必须看起来像std::is_integral_v<T> && !std::is_floating_point_v<T>
。
这里发生的是std::enable_if_t
造成其中一个重载&#34;无法编译&#34;如果不满足条件,这意味着由于SFINAE而无法考虑过载。
如果您使用的是C ++ 17,则可能需要考虑使用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
}
}
答案 1 :(得分:3)
根据您的完整意图,在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;
}
希望可以提供帮助。
答案 2 :(得分:0)
根据SFINAE,我们可以为一种类型设计编译错误,而让另一种进入模板替换阶段。对于整数类型与浮点类型,我们可以使用与位相关的运算符来处理诸如~
之类的整数。例如,
#include <iostream>
template <typename T, T=~0>
void f_(T a, int) // additional tags for unambiguous overloading, same below
{
std::cout << a << " is of integral type." << std::endl;
}
template <typename T>
void f_(T a, char)
{
std::cout << a << " is of floating-point type." << std::endl;
}
template <typename T>
void f(T a)
{
f_<T>(a, 0);
}
int main()
{
f<char>('a');
f<int>(0);
f<float>(1.5f);
f<double>(2.5);
return 0;
}
给予
a is of integral type.
0 is of integral type.
1.5 is of floating-point type.
2.5 is of floating-point type.