簡體   English   中英

std::enable_if 如何工作?

[英]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 Condtrue時才定義。

現在有了對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>::typevoidstd::enable_if的默認第二個參數,並且如果您有 enable_if_t是一個定義的類型,應該使用。 所以返回類型應該壓縮為: std::enable_if_t<std::numeric_limits<T>::is_integer>

為用戶特別注意之前, :默認模板參數不支持,所以你只能將能夠使用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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM