模板专业化和 enable_if 问题
Template specialization and enable_if problems
我 运行 遇到了关于适当使用 enable_if 和模板专业化的问题。
修改示例后(出于保密原因),这里有一个可比较的示例:
I have function called "less" that checks if 1st arg is less than 2nd
arg. Let's say I want to have 2 different kinds of implementations
depending on the type of input - 1 implementation for integer and
another for double.
我目前的代码如下所示 -
#include <type_traits>
#include <iostream>
template <class T,
class = typename std::enable_if<std::is_floating_point<T>::value>::type>
bool less(T a, T b) {
// ....
}
template <class T,
class = typename std::enable_if<std::is_integral<T>::value>::type>
bool less(T a, T b) {
// ....
}
int main() {
float a;
float b;
less(a,b);
return 0;
}
以上代码无法编译,因为 - 它说我正在重新定义 less 方法。
错误是:
Z.cpp:15:19: error: template parameter redefines default argument
class = typename std::enable_if<std::is_integral<T>::value>::type>
^
Z.cpp:9:19: note: previous default template argument defined here
class = typename std::enable_if<std::is_floating_point<T>::value>::type>
^
Z.cpp:16:11: error: redefinition of 'less'
bool less(T a, T b) {
^
Z.cpp:10:11: note: previous definition is here
bool less(T a, T b) {
^
Z.cpp:23:5: error: no matching function for call to 'less'
less(a,b);
^~~~
Z.cpp:15:43: note: candidate template ignored: disabled by 'enable_if'
[with T = float]
class = typename std::enable_if<std::is_integral<T>::value>::type>
^
3 errors generated.
谁能指出这里的错误是什么?
默认模板参数不是函数模板签名的一部分。因此,在您的示例中,您有两个相同的 less
重载,这是非法的。 clang 抱怨默认参数的重新定义(根据 §14.1/12 [temp.param],这也是非法的),而 gcc 产生以下错误消息:
error: redefinition of 'template<class T, class> bool less(T, T)
'
要修复错误,请将 enable_if
表达式从默认参数移动到虚拟模板参数
template <class T,
typename std::enable_if<std::is_floating_point<T>::value, int>::type* = nullptr>
bool less(T a, T b) {
// ....
}
template <class T,
typename std::enable_if<std::is_integral<T>::value, int>::type* = nullptr>
bool less(T a, T b) {
// ....
}
另一种选择是在 return 类型中使用 enable_if
,尽管我觉得这更难阅读。
template <class T>
typename std::enable_if<std::is_floating_point<T>::value, bool>::type
less(T a, T b) {
// ....
}
template <class T>
typename std::enable_if<std::is_integral<T>::value, bool>::type
less(T a, T b) {
// ....
}
我 运行 遇到了关于适当使用 enable_if 和模板专业化的问题。
修改示例后(出于保密原因),这里有一个可比较的示例:
I have function called "less" that checks if 1st arg is less than 2nd arg. Let's say I want to have 2 different kinds of implementations depending on the type of input - 1 implementation for integer and another for double.
我目前的代码如下所示 -
#include <type_traits>
#include <iostream>
template <class T,
class = typename std::enable_if<std::is_floating_point<T>::value>::type>
bool less(T a, T b) {
// ....
}
template <class T,
class = typename std::enable_if<std::is_integral<T>::value>::type>
bool less(T a, T b) {
// ....
}
int main() {
float a;
float b;
less(a,b);
return 0;
}
以上代码无法编译,因为 - 它说我正在重新定义 less 方法。
错误是:
Z.cpp:15:19: error: template parameter redefines default argument
class = typename std::enable_if<std::is_integral<T>::value>::type>
^
Z.cpp:9:19: note: previous default template argument defined here
class = typename std::enable_if<std::is_floating_point<T>::value>::type>
^
Z.cpp:16:11: error: redefinition of 'less'
bool less(T a, T b) {
^
Z.cpp:10:11: note: previous definition is here
bool less(T a, T b) {
^
Z.cpp:23:5: error: no matching function for call to 'less'
less(a,b);
^~~~
Z.cpp:15:43: note: candidate template ignored: disabled by 'enable_if'
[with T = float]
class = typename std::enable_if<std::is_integral<T>::value>::type>
^
3 errors generated.
谁能指出这里的错误是什么?
默认模板参数不是函数模板签名的一部分。因此,在您的示例中,您有两个相同的 less
重载,这是非法的。 clang 抱怨默认参数的重新定义(根据 §14.1/12 [temp.param],这也是非法的),而 gcc 产生以下错误消息:
error: redefinition of '
template<class T, class> bool less(T, T)
'
要修复错误,请将 enable_if
表达式从默认参数移动到虚拟模板参数
template <class T,
typename std::enable_if<std::is_floating_point<T>::value, int>::type* = nullptr>
bool less(T a, T b) {
// ....
}
template <class T,
typename std::enable_if<std::is_integral<T>::value, int>::type* = nullptr>
bool less(T a, T b) {
// ....
}
另一种选择是在 return 类型中使用 enable_if
,尽管我觉得这更难阅读。
template <class T>
typename std::enable_if<std::is_floating_point<T>::value, bool>::type
less(T a, T b) {
// ....
}
template <class T>
typename std::enable_if<std::is_integral<T>::value, bool>::type
less(T a, T b) {
// ....
}