給定任何型別 T 時手動區分型別

使用 std::enable_if 實現 SFINAE 時 ,訪問輔助模板通常很有用,可以確定給定型別 T 是否與一組條件匹配。

為了幫助我們,該標準已經提供了兩種型別的 truefalse,分別是 std::true_typestd::false_type

以下示例顯示如何檢測型別 T 是否為指標,is_pointer 模板模仿標準 std::is_pointer 幫助程式的行為:

template <typename T>
struct is_pointer_: std::false_type {};

template <typename T>
struct is_pointer_<T*>: std::true_type {};

template <typename T>
struct is_pointer: is_pointer_<typename std::remove_cv<T>::type> { }

上面的程式碼有三個步驟(有時你只需要兩個):

  1. is_pointer_ 的第一個宣告是預設情況,並繼承自 std::false_type。在預設的情況下,應始終從 std::false_type 繼承,因為它是類似於一個“false 條件”。

  2. 第二個宣告專門用於指示 T*is_pointer_ 模板,而不關心 T 究竟是什麼。此版本繼承自 std::true_type

  3. 第三個宣告(真正的宣告)只是從 T 刪除任何不必要的資訊(在這種情況下我們刪除了 constvolatile 限定符),然後回退到前兩個宣告中的一個。

由於 is_pointer<T> 是一個類,要訪問它的值,你需要:

  • 使用::value,例如 is_pointer<int>::value - valuebool 的靜態類成員,繼承自 std::true_typestd::false_type;
  • 構造一個這種型別的物件,例如 is_pointer<int>{} - 這是因為 std::is_pointerstd::true_typestd::false_type(有 constexpr 建構函式)繼承了它的預設建構函式,std::true_typestd::false_type 都有 constexpr 轉換運算子到 bool

提供幫助程式幫助程式模板是一個很好的習慣,可以讓你直接訪問該值:

template <typename T>
constexpr bool is_pointer_v = is_pointer<T>::value;

Version >= C++ 17

在 C++ 17 及更高版本中,大多數幫助器模板已經提供了 _v 版本,例如:

template< class T > constexpr bool is_pointer_v = is_pointer<T>::value;
template< class T > constexpr bool is_reference_v = is_reference<T>::value;