【发布时间】:2019-10-21 14:52:06
【问题描述】:
在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),那么它就是一个函数类型。。但是,我找不到这行的含义:
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 总是错误的。
但我一定是搞错了。谁能指出我?
【问题讨论】:
-
除非我是盲人,否则
sizeof的行有 3 个开头的<,但只有两个结尾的>... -
抱歉我的错字。谢谢你的评论。我现在就编辑它。
-
你在哪里找到这个定义?我在 libc++ 源代码中看到了something else。它基本上使用clang
__is_function内在函数。 -
请注意,他们后来想出了一个更聪明的实现(参见patch)。这个想法是引用和函数类型是唯一可以忽略添加 cv 限定的类型。
-
@DanielLangr 我在github.com/llvm/llvm-project/blob/release/9.x/libcxx/include/… 中找到了这个定义,它在
release/9.x分支中。
标签: c++ c++11 typetraits libc++