我正在尝试使用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
}
但是在尝试编译时,带有std :: enable_if的模板函数似乎没有参与解析,因此编译器告诉我没有与我的函数调用匹配的函数。我尝试使用返回类型的std::enable_if
,但也没有运气。我确信在这段代码中我有一些错误,或者我正在尝试以错误的方式执行此操作。
我试图不写每个int专门化(int,short,long ,很长,...),所以有人有这个解决方案吗?
答案 0 :(得分:4)
我对代码进行了一些更改,从无约束功能模板开始。由于您分别处理算术类型,因此只有在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;}
现在,您为整数和浮点类型定义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;
}
最后,没有必要专门处理Ip
,而是创建一个重载。
//Overload
bool Equal(const std::string& s, const Ip& data)
{
//Ip specific
return false;
}
答案 1 :(得分:3)
以下作品:(https://ideone.com/G1vJKm)
#include <string>
#include <type_traits>
struct Ip
{
std::string ip;
};
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;}
template <typename T>
typename std::enable_if<std::is_integral<T>::value, bool>::type
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, bool>::type
Equal(const std::string& s, const T& data)
{
//Float specific
return false;
}
bool Equal(const std::string& s, const Ip& data)
{
//Ip specific
return false;
}
在你的情况下,
template <typename T>
bool Equal(const std::string& s, const T& data)
是所有T
的有效候选者,也适用于积分和浮点。
您的其他模板函数,编译器无法推断T
的{{1}}类型。
对于typename std::enable_if<std::is_integral<T>::value, T>::type
版本,更简单的过载就足够了(并且首选)。