問題描述
我遇到了有關 enable_if 和模板特化的適當用法的問題.
I am running into a problem regarding the appropriate usage of enable_if and template specialization.
修改示例后(出于保密原因),這是一個可比較的示例:
After modifying the example (for confidentiality reasons), here's a comparable example:
我有一個名為less"的函數,用于檢查第一個參數是否小于第二個參數arg.假設我想要兩種不同的實現取決于輸入的類型 - 1 個整數和另一個雙倍.
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.
到目前為止我的代碼看起來像這樣 -
The code that I have so far looks like this -
#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 方法.
The above code does not compile because - It says that I am re-defining the less method.
錯誤是:
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.
有人能指出這里的錯誤嗎?
Can someone point out what's the mistake here?
推薦答案
默認模板參數不是函數模板簽名的一部分.因此,在您的示例中,您有兩個相同的 less
重載,這是非法的.clang 抱怨默認參數的重新定義(根據 §14.1/12 [temp.param] 這也是非法的),而 gcc 產生以下錯誤消息:
Default template arguments are not part of the signature of a function template. So in your example you have two identical overloads of less
, which is illegal. clang complains about the redefinition of the default argument (which is also illegal according to §14.1/12 [temp.param]), while gcc produces the following error message:
錯誤:重新定義'template
'
要修復錯誤,請將 enable_if
表達式從默認參數移動到虛擬模板參數
To fix the error move the enable_if
expression from default argument to a dummy template parameter
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) {
// ....
}
<小時>
另一種選擇是在返回類型中使用 enable_if
,雖然我覺得這更難閱讀.
Another option is to use enable_if
in the return type, though I feel this is harder to read.
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 問題的文章就介紹到這了,希望我們推薦的答案對大家有所幫助,也希望大家多多支持html5模板網!