是否可以根据类型是整数类型还是浮点类型来重载模板函数?

问题描述 投票:1回答:3

我想编写模板函数,当类型为整数时应调用该函数,例如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
}
c++ function templates
3个回答
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个条件必须是不相交的,我们可以从enable_ifstd::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>

3
投票

根据您的全部意图,在std::enable_if_tif 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
    }
}

希望有所帮助。


0
投票

根据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
© www.soinside.com 2019 - 2024. All rights reserved.