[英]How Does std::enable_if work?
我剛剛問了這個問題: std::numeric_limits as a Condition
我理解std::enable_if
將有條件地定義方法的返回類型導致方法無法編譯的用法。
template<typename T>
typename std::enable_if<std::numeric_limits<T>::is_integer, void>::type foo(const T &bar) { isInt(bar); }
我不明白的是第二個參數以及當std::enable_if
被聲明為模板語句的一部分時看似毫無意義的賦值,如Rapptz answer 。
template<typename T, typename std::enable_if<std::is_integral<T>::value, int>::type = 0>
void foo(const T& bar) { isInt(); }
正如40two在評論中提到的,理解替換失敗不是錯誤是理解std::enable_if
的先決條件。
std::enable_if
是一個專門的模板,定義為:
template<bool Cond, class T = void> struct enable_if {};
template<class T> struct enable_if<true, T> { typedef T type; };
這里的關鍵在於typedef T type
僅在bool Cond
為true
時才定義。
現在有了對std::enable_if
理解,很明顯void foo(const T &bar) { isInt(bar); }
void foo(const T &bar) { isInt(bar); }
被定義為:
template<typename T>
typename std::enable_if<std::numeric_limits<T>::is_integer, void>::type foo(const T &bar) { isInt(bar); }
如firda's answer所述, = 0
是第二個模板參數的默認值。 在template<typename T, typename std::enable_if<std::is_integral<T>::value, int>::type = 0>
默認的原因是這兩個選項都可以用foo< int >( 1 );
. 如果std::enable_if
模板參數沒有被默認,調用foo
將需要兩個模板參數,而不僅僅是int
。
一般注意,通過顯式鍵入typename std::enable_if<std::numeric_limits<T>::is_integer, void>::type
但void
是std::enable_if
的默認第二個參數,並且如果您有c++14 enable_if_t
是一個定義的類型,應該使用。 所以返回類型應該壓縮為: std::enable_if_t<std::numeric_limits<T>::is_integer>
為用戶特別注意視覺工作室之前, 視覺工作室2013 :默認模板參數不支持,所以你只能將能夠使用enable_if
在函數返回: 的std :: numeric_limits作為條件
template<typename T, std::enable_if<std::is_integral<T>::value, int>::type = 0>
void foo(const T& bar) { isInt(); }
如果T
不是整數,則編譯失敗(因為enable_if<...>::type
不會被定義)。 它是對函數foo
保護。賦值= 0
用於默認模板參數以隱藏它。
另一種可能性:(是的typename
丟失在原來的問題)
#include <type_traits>
template<typename T, typename std::enable_if<std::is_integral<T>::value, int>::type = 0>
void foo(const T& bar) {}
template<typename T>
typename std::enable_if<std::is_integral<T>::value>::type
bar(const T& foo) {}
int main() {
foo(1); bar(1);
foo("bad"); bar("bad");
}
error: no matching function for call to ‘foo(const char [4])’ foo("bad"); bar("bad"); ^ note: candidate is: note: template::value, int>::type > void foo(const T&) void foo(const T& bar) {} ^ note: template argument deduction/substitution failed: error: no type named ‘type’ in ‘struct std::enable_if’ template::value, int>::type = 0> ^ note: invalid template non-type parameter error: no matching function for call to ‘bar(const char [4])’ foo("bad"); bar("bad"); ^
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.