[我试图理解std::enable_if
,cppreference.com有一个示例,这种使用比函数重载有什么好处?
struct T {
enum { int_t,float_t } m_type;
template <typename Integer,
std::enable_if_t<std::is_integral<Integer>::value, int> = 0
>
T(Integer) : m_type(int_t) {}
>
template <typename Floating,
std::enable_if_t<std::is_floating_point<Floating>::value, int> = 0
>
T(Floating) : m_type(float_t) {} // OK
};
struct T1 {
enum { int_t, float_t } m_type;
T1(int) :m_type(int_t)
{
cout << "int ctor" << endl;
}
T1(float) :m_type(float_t)
{
cout << "float ctor" << endl;
}
};
您的两个示例不相同。对于第一个示例,该类将排除任何整数或浮点类型exactly。在第二个示例中,您仅采用int
或float
的含义,如果您通过了long long
或double
,则可能会缩小转换范围,从而可能导致数据丢失。这与您使用的代码无关紧要,但是可以并且应该提防它。
[使用一种可以转换为float
或int
的类型时,您也会感到含糊。例如
T1 foo{0l};
不会编译但是
T foo{0l};
将。
在这种情况下,实际上并没有真正的优势,因为整数类型会转换为例如int
首先,然后将调用正确的重载构造函数。
但是,假设您想创建一个仅接受整数的函数。它应该返回作为参数接收的整数类型。在那种情况下,手动创建> 10个重载只是容易出错/愚蠢/烦人/ ...,相反,您将编写如下内容:
template <typename Integer,
std::enable_if_t<std::is_integral<Integer>::value, int> = 0>
Integer doMagic (Integer a) {
return a;
}