簡體   English   中英

libcxx 中 std::is_function 的實現如何工作?

[英]How does the impementation for std::is_function in libcxx work?

libcxx/include/type_traits中, std::is_function以如此緊湊的方式實現:

namespace __libcpp_is_function_imp
{
struct __dummy_type {};
template <class _Tp> char  __test(_Tp*);
template <class _Tp> char __test(__dummy_type);
template <class _Tp> __two __test(...);
template <class _Tp> _Tp&  __source(int);
template <class _Tp> __dummy_type __source(...);
}

template <class _Tp, bool = is_class<_Tp>::value ||
                            is_union<_Tp>::value ||
                            is_void<_Tp>::value  ||
                            is_reference<_Tp>::value ||
                            __is_nullptr_t<_Tp>::value >
struct __libcpp_is_function
    : public integral_constant<bool,
                               sizeof(__libcpp_is_function_imp::__test<_Tp>(
                                      __libcpp_is_function_imp::__source<_Tp>(0))) == 1>
    {};
template <class _Tp> struct __libcpp_is_function<_Tp, true> : public false_type {};

template <class _Tp> struct _LIBCPP_TEMPLATE_VIS is_function
    : public __libcpp_is_function<_Tp> {};

我明白了一般的想法。 如果一個類型與任何非函數類型(class、union、void、reference、nullptr_t)都不匹配,則它是 function 類型。 . 但是,我找不到這一行的含義:

sizeof(__libcpp_is_function_imp::__test<_Tp>(__libcpp_is_function_imp::__source<_Tp>(0))) == 1

我認為, __libcpp_is_function_imp::__source<_Tp>(0)的結果類型應該是_Tp& 所以__libcpp_is_function_imp::__test<_Tp>(_Tp&)的結果類型應該是_two 並且sizeof(_two)應該等於 2,這與1不同。 換句話說,方程sizeof(__libcpp_is_function_imp::__test<_Tp>(__libcpp_is_function_imp::__source<_Tp>(0))) == 1總是錯誤的。

但我一定是搞錯了。 誰能指出我?

C++ 中的每種類型都恰好屬於以下類別之一,可能是 cv 限定的:

  • void
  • decltype(nullptr) (又名std::nullptr_t
  • 算術
  • 大批
  • 指針(,某些類型TT*
  • 參考(左值或右值)
  • 指向非靜態成員的指針
  • 枚舉
  • classstruct
  • union
  • Function

在消除classunionvoid 、reference 和std::nullptr_t ,我們剩下以下可能的類型:

  • 算術
  • 大批
  • 指針
  • 指向非靜態成員的指針
  • 枚舉
  • Function

剩下的模板元編程利用了關於這些剩余類別中的類型的兩個事實:

  • 如果_Tp可惡的 function 類型,則創建引用類型_Tp&的嘗試是錯誤的。 否則, _Tp&是格式良好的。
  • 否則,當且僅當_Tp是 function 類型時,類型_Tp才能通過函數到指針的轉換轉換為_Tp*

它留給讀者作為練習來確定為什么在此測試正常工作之前必須在早期階段消除classunionvoid 、 reference 和std::nullptr_t類型。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

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