【发布时间】:2016-02-21 01:43:06
【问题描述】:
当D(删除器类型)是 lambda 函数类型,但更大当D 是函数指针类型时的大小(因为需要在unique_ptr 实例中分配空间来存储函数指针)。
查看VS2015源码,发现std::unique_ptr派生自std::_Unique_ptr_base,又声明了_Compressed_pair<class _Ty1, class _Ty2, bool = is_empty<_Ty1>::value && !is_final<_Ty1>::value>类型的数据成员。在后一种情况下,_Ty1 类型是删除器的类型,D,即上一段中提到的第二个unique_ptr 模板参数;即,这个问题背后的动机是我将_Ty1 是一个 lambda 类型,而 _Ty1 是一个函数指针类型。 (实际上,bool 的默认值正在被使用。)
当 _Ty1 是 lambda 类型的实例时(当 lambda 没有捕获变量因此大小为 0 时),我认识到 is_empty<_Ty1>::value 是 true;但当_Ty1 是函数指针类型时,它是false。
这让我开始研究std::is_empty 是如何定义的。
啊!
下面是我可以在VS2015 C++库源代码中找到的std::is_empty的完整实现。
在文件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 的定义。我已经通过 GREP 遍历了整个 VS2015 安装目录(我认为其中包括所有 C++ 库源代码,尽管我可能弄错了)。
我喜欢在需要时了解 C++ 内部结构。但是......我被困在这个问题上,大量的谷歌搜索并没有揭示答案(尽管我已经看到对内在函数的引用),而且我的挖掘没有......发现任何源代码。
有人可以启发这种情况吗? std::is_empty<T> 是如何在 VS2015 或任何其他编译器中实际实现的?
【问题讨论】:
-
我不确定,但根据标准,空类的大小为 1 字节。可以衡量类的大小并确定。我还没有真正尝试过实现这个
-
@DavidHaim - 这种推理与 Dietmar Kühl 提供的答案有关。在他回答的示例中,他利用了这样一个事实,即当非空类派生自空类时,空类子对象 does 的大小为 0 - 只有当类是完全为空,包括该类必须具有非零大小的所有基类子对象。
标签: c++ c++11 stl visual-studio-2015 typetraits