模板函數需對特定類型 (如 int/double) 做特化處理,但模板參數 TYPE 在編譯期是未知的。C++11 <type_traits> 提供了編譯期類型檢查工具,核心是 std::is_same 與 std::decay。
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<T>::type 模擬函數參數傳值時的類型轉換:
T& / T&& → T)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 引入 std::is_same_v<T, U> (變量模板) 與 std::decay_t<T> (別名模板),代碼更簡潔:
if constexpr (std::is_same_v<std::decay_t<T>, int>) { /* ... */ }
std::is_same 用於**嚴格**類型比對,不自動處理引用、cv 資格、數組退化。std::decay 模擬**傳值語義**的類型轉換,剝離修飾層。std::is_same<std::decay_t<T>, Target>::value 是模板元編程中判斷「本質類型」的標準模式。char、signed char、unsigned char 是三個不同類型,is_same 會嚴格區分。