是否可以根据类型是整数类型还是浮点类型重载模板函数
Is it possible to overload a template function based on whether the type is an integer type or a floating point type?
我想编写模板函数,该函数应该在类型为整数时调用,例如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 个条件必须是不相交的,我们可以从std::is_integral
和std::is_floating_point
的文档中看到它们是不相交的。如果不是这样,条件必须看起来像std::is_integral_v<T> && !std::is_floating_point_v<T>
。
这里发生的事情是,如果不满足条件,std::enable_if_t
会使其中一个重载"无法编译",这意味着由于 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
}
}
根据您的全部意图,在 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,我们可以为一种类型设计编译错误,同时让另一种类型进入模板替换阶段。在整型与浮点型的情况下,我们可以对整数使用与位相关的运算符,例如 ~
。例如
#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.
相关文章:
- 是否使用cv::Point2f类型重载std::排序
- 如何使用common_type和模板递归类型重载运算符+
- 按返回类型重载函数模板
- 是否可以根据类型是整数类型还是浮点类型重载模板函数
- 使用 ostream 和枚举类型重载<<
- 如何根据数组参数项类型重载 IDL 中的函数
- 按参数中的向量类型重载函数
- 如何使用内置返回类型重载运算符?
- 同时使用参数重载和返回类型重载
- 使用子类型重载调用函数
- 按返回类型重载模板
- 基于参数函数参数类型重载函数模板
- C++类型 重载仅部分起作用
- 提升::任何构造函数 - 常量类型重载分辨率
- 按函子参数计数类型C++重载
- C++类型重载问题
- 按返回类型重载
- C++按返回类型重载函数
- 如何包装按类型重载的函数
- 使用专门的模板根据返回类型重载函数