使用 std::enable_if

Kir*_*xas 3 c++ templates enable-if c++11

我正在尝试使用 来专门针对一系列类型的函数std::enable_if
这是我想要完成的任务的一个更简单的版本。

#include <type_traits>
#include <string>

struct Ip
{};

template <typename T>
bool Equal(const std::string& s, const T& data)
{return s == data;}

template <typename T>
bool Equal(const std::string& s, const typename std::enable_if<std::is_integral<T>::value, T>::type& data)
{
    //int specific
}

template <typename T>
bool Equal(const std::string& s, const typename std::enable_if<std::is_floating_point<T>::value, T>::type& data)
{
    //Float specific
}

//Specialization
template <> bool Equal(const std::string& s, const Ip& data)
{
   //Ip specific
} 

int main()
{
    //Equal("21",21); // Do not compile
    Equal("21","42.5"); // Compile
}
Run Code Online (Sandbox Code Playgroud)

但是当尝试编译时,模板函数std::enable_if似乎不参与解析,因此编译器告诉我没有与我的函数调用匹配的函数。我尝试使用std::enable_if返回类型,但也没有运气。我确信我在这段代码中做了一些非常错误的事情,或者也许我试图以错误的方式来做这件事。
我试图不写每个 int 专业化(int,short,long,long long,...),那么有人有解决方案吗?

Pra*_*ian 5

我将从无约束函数模板开始对您的代码进行一些更改。T由于您要单独处理算术类型,因此仅当既不是整数也不是浮点时才应该选择它。

template <typename T>
typename std::enable_if<!std::is_integral<T>::value &&
                        !std::is_floating_point<T>::value, bool>::type 
    Equal(const std::string& s, const T& data)
{return s == data;}
Run Code Online (Sandbox Code Playgroud)

Equal现在,您为整型和浮点类型定义的方式导致T成为非推导上下文。因此,将 移至enable_if虚拟模板参数以允许推导(您也可以使用返回类型,如上所述)。

template <typename T,
          typename std::enable_if<std::is_integral<T>::value, T>::type* = nullptr>
bool Equal(const std::string& s, const T& data)
{
    //int specific
    return false;
}

template <typename T,
          typename std::enable_if<std::is_floating_point<T>::value, T>::type* = nullptr>
bool Equal(const std::string& s, const T& data)
{
    //Float specific
    return false;
}
Run Code Online (Sandbox Code Playgroud)

最后,不需要专门处理Ip,而是创建一个重载。

//Overload
bool Equal(const std::string& s, const Ip& data)
{
   //Ip specific
    return false;
}
Run Code Online (Sandbox Code Playgroud)

现场演示