首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> C語言 >> C++ >> 關於C++

C++11 模板類型判斷利器:std::is_same 與 std::decay 深度解析

     編輯:關於C++

問題場景:編譯期如何區分 int 與 double?

模板函數需對特定類型 (如 int/double) 做特化處理,但模板參數 TYPE 在編譯期是未知的。C++11 <type_traits> 提供了編譯期類型檢查工具,核心是 std::is_same 與 std::decay。

std::is_same:嚴格的類型相等判斷

std::is_same<T, U>::value 僅當 T 與 U 完全相同 (含 cv 資格、引用、數組/函數退化) 時為 true。

std::is_same<int, int>::value;           // true
std::is_same<int, const int>::value;     // false (cv 資格不同)
std::is_same<int, int&>::value;          // false (引用不同)
std::is_same<int, int[]>::value;         // false (數組未退化)

陷阱:模板參數推導時,TYPE 可能被推導為 const int&、int[10] 等,導致 is_same<TYPE, int> 失效。

std::decay:類型「退化」去修飾

std::decay<T>::type 模擬函數參數傳值時的類型轉換:

  • 移除引用 (T& / T&& → T)
  • 移除 cv 資格 (const T / volatile T → T)
  • 數組退化為指針 (T[N] → T*)
  • 函數退化為函數指針 (Ret(Args...) → Ret(*)(Args...))
std::decay<const int&>::type   // int
std::decay<int[10]>::type      // int*
std::decay<void(int)>::type    // void(*)(int)

組合拳:通用類型判斷工具

template <typename T>
void typeCheck(T&& data) {
    using Decayed = typename std::decay<T>::type;
    if (std::is_same<Decayed, int>::value) {
        std::cout << "int type\n";
    } else if (std::is_same<Decayed, double>::value) {
        std::cout << "double type\n";
    } else {
        std::cout << "other type\n";
    }
}

int a = 1;
const int& b = a;
int&& c = 1;
typeCheck(a);  // int type
typeCheck(b);  // int type (decay 移除 const&)
typeCheck(c);  // int type (decay 移除 &&)
typeCheck(3.14); // double type

進階應用:C++17 變體

C++17 引入 std::is_same_v<T, U> (變量模板) 與 std::decay_t<T> (別名模板),代碼更簡潔:

if constexpr (std::is_same_v<std::decay_t<T>, int>) { /* ... */ }

總結

  1. std::is_same 用於**嚴格**類型比對,不自動處理引用、cv 資格、數組退化。
  2. std::decay 模擬**傳值語義**的類型轉換,剝離修飾層。
  3. 兩者結合:std::is_same<std::decay_t<T>, Target>::value 是模板元編程中判斷「本質類型」的標準模式。
  4. 注意 char、signed char、unsigned char 是三個不同類型,is_same 會嚴格區分。
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved