我的当前问题是通过尝试了解如何std::unique_ptr<T, D>
利用模板机制来实例化模板类而启发的,而T*
当D
(删除器类型)为lambda函数类型时,其大小D
为;而当函数指针类型为(由于空间需要在unique_ptr
实例中分配以存储函数指针)。
查看VS2015源代码,我发现std::unique_ptr
从派生std::_Unique_ptr_base
,后者又声明了type的数据成员_Compressed_pair<class _Ty1, class _Ty2, bool = is_empty<_Ty1>::value && !is_final<_Ty1>::value>
。类型_Ty1
在后一种情况下是删除器的类型,D
即该第二unique_ptr
在前面段落中提到的模板参数; 即,这个问题背后的动机是,我对比的_Ty1
是lambda类型,而_Ty1
不是函数指针类型。(实际上,bool
正在使用的默认值。)
我知道那is_empty<_Ty1>::value
是true
何时_Ty1
是lambda类型的实例(当lambda没有捕获变量,因此大小为0时);但是它是false
何时_Ty1
是函数指针类型。
这导致我追求如何std::is_empty
定义。
啊!
接下来是std::is_empty
我可以在VS2015 C ++库源代码中找到的完整实现。
在文件中type_traits
是这样的:
// TEMPLATE CLASS is_empty
template<class _Ty>
struct is_empty _IS_EMPTY(_Ty)
{ // determine whether _Ty is an empty class
};
...,并且宏_IS_EMPTY
在同一文件中定义:
#define _IS_EMPTY(_Ty) \
: _Cat_base<__is_empty(_Ty)>
……这时我的运气一团糟,因为我找不到__is_empty
任何地方的定义。我已经遍历整个VS2015安装目录(我认为其中包括所有C ++库源代码,尽管-我可能会误解)。
我想要了解C ++内部知识。但是……我被困在这一点上,大量的谷歌搜索并没有给出答案(尽管我已经看到了对内在函数的引用),而且我的挖掘工作还没有发现任何源代码。
有人可以启发这种情况吗?如何std::is_empty<T>
在VS2015或其他任何编译器中实际实现?
看起来MSVC ++提供了一个内在的__isempty(T)
而不是处理库级别的实现。由于T
传递给的参数类型std::is_empty<T>
可以是final
,我认为不可能有一个安全的库实现,可能不需要编译器帮助。
确定一个类型的唯一方法T
是我能想到的库空是这(与非专业化的交易class
类型这std::is_empty<T>
是不是true
):
template <bool, typename T>
struct is_empty_aux: T { unsigned long long dummy; };
template <typename T>
struct is_empty_aux<false, T> { unsigned long long dummy[2]; };
template <typename T>
struct is_empty:
std::integral_constant<bool,
sizeof(is_empty_aux<std::is_class<T>::value, T>)
== sizeof(unsigned long long)> {
};
但是,如果T
是final
在继承is_empty_aux
是非法的。虽然final
可以使用检测到类的情况,但std::is_final<T>
我没有找到确定其对象是否为空的方法。因此,可能需要使用内部编译器。无论如何,对于某些其他类型特性,编译器内在函数当然是必需的。编译器内部函数是编译器以某种方式神奇地提供的声明/定义:它们通常既不显式声明也不定义。编译器具有有关类型的必要知识,并且通过内在函数公开此知识是一种合理的方法。
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句