【C++】【原始碼解讀】std::is_same函式原始碼解讀

鈴靈狗發表於2022-02-09

std::is_same使用很簡單 重點在於對原始碼的解讀

參考下面一句靜態斷言:

static_assert(!std::is_same<bool, T>::value, "vector<bool> is abandoned in mystl");

靜態斷言優點:可以自定義斷言失敗之後的輸出 便於debug找問題
其中我們用到了std::is_same
點進is_same進行原始碼分析:

  template<typename, typename>
    struct is_same
    : public false_type { };

  template<typename _Tp>
    struct is_same<_Tp, _Tp>
    : public true_type { };

可以看出兩種is_same分別繼承於兩個不同的結構體
再來看看false_type和true_type的定義:

typedef integral_constant<bool, true>     true_type;
typedef integral_constant<bool, false>    false_type;

可以看出這兩個來自於同一個結構體模版:integral_constant
繼續看integral_constant的定義:

  template<typename _Tp, _Tp __v>
    struct integral_constant
    {
      static constexpr _Tp                  value = __v;
      typedef _Tp                           value_type;
      typedef integral_constant<_Tp, __v>   type;
      constexpr operator value_type() const noexcept { return value; }
#if __cplusplus > 201103L

#define __cpp_lib_integral_constant_callable 201304

      constexpr value_type operator()() const noexcept { return value; }
#endif
    };

下面的巨集定義不用管
可以看出這個模版需要一個_Tp類 然後還需要一個非模版型別的引數_v 並且這個引數的型別和_Tp的型別相同 並且會把這個非模版型別引數_v賦值給結構體成員變數
記得我們最開始呼叫is_same時

static_assert(!std::is_same<bool, T>::value, "vector<bool> is abandoned in mystl");

原來斷言的就是這個value的值(一定是個bool且必須是個bool)
回到上一步false_type和true_type的定義:

typedef integral_constant<bool, true>     true_type;
typedef integral_constant<bool, false>    false_type;

可以看出實際上是起了兩個別名 true_type結構體中包含的value成員變數一定是true flase_type結構體中包含的value成員變數一定是false 我們需要斷言的也就是這個value的值 再往回導一步:

  template<typename, typename>
    struct is_same
    : public false_type { };

  template<typename _Tp>
    struct is_same<_Tp, _Tp>
    : public true_type { };

這個是模版呼叫優先順序的問題 實際上 當傳入相同型別的引數時(std::is_same<bool, bool>)此時會直接呼叫下面的is_same 反之如果兩個型別不同 則會呼叫上面的is_same
所以最開始我們的呼叫:

static_assert(!std::is_same<bool, T>::value, "vector<bool> is abandoned in mystl");

這裡的實際要求是不能傳入bool型別的變數 即vector不接受bool型別
這設計思路真的很棒
原始碼地址是github上開源的自己手寫STL

相關文章