在VS2015(或任何编译器)中如何实现std :: is_empty <T>?

丹·尼森鲍姆

我的当前问题是通过尝试了解如何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>::valuetrue何时_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或其他任何编译器中实际实现?

迪特玛·库尔(DietmarKühl)

看起来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)> {
};

但是,如果Tfinal在继承is_empty_aux是非法的。虽然final可以使用检测到类的情况,但std::is_final<T>我没有找到确定其对象是否为空的方法。因此,可能需要使用内部编译器。无论如何,对于某些其他类型特性,编译器内在函数当然是必需的。编译器内部函数是编译器以某种方式神奇地提供的声明/定义:它们通常既不显式声明也不定义。编译器具有有关类型的必要知识,并且通过内在函数公开此知识是一种合理的方法。

本文收集自互联网,转载请注明来源。

如有侵权,请联系[email protected] 删除。

编辑于
0

我来说两句

0条评论
登录后参与评论

相关文章

来自分类Dev

队列数据结构中is_empty的线程安全实现

来自分类Dev

.NET编译器如何为HashSet <T>中的任何T构造O(1)查找?

来自分类Dev

如何在std :: atomic <T>上实现简单的自旋锁,以使编译器不会对其进行优化?

来自分类Dev

如何在std :: atomic <T>上实现简单的自旋锁,以使编译器不会对其进行优化?

来自分类Dev

无法在VS2015中禁用编译器警告

来自分类Dev

Boost :: filesystem :: is_empty()为Symlinks返回false

来自分类Dev

将is_empty添加到哈希表

来自分类Dev

如何在VS2015中使用T4模板生成多个文件输出?

来自分类Dev

尝试创建和使用一个类;未定义名称“ is_empty”

来自分类Dev

如何使C ++编译器间接推导T?

来自分类Dev

“无法将参数1从'Node <T>'转换为'std :: nullptr_t”编译器错误

来自分类Dev

如何在VS2015中使用T4?(未找到Microsoft.TextTemplating.targets文件)

来自分类Dev

使用VS2010编译器编译VS2015项目

来自分类Dev

为什么VS 2015编译器无法在abs()实现中优化浮点数的分支?

来自分类Dev

编译器在VS2015中显示“表达式必须具有恒定值”(C编程)

来自分类Dev

禁用VS2015 C#编译器自动生成[Serializable]属性

来自分类Dev

VS2015编译器将忽略对我的DLL的所有引用

来自分类Dev

禁用VS2015 C#编译器自动生成[Serializable]属性

来自分类Dev

Scala:如何让编译器从Seq [T]类型的函数参数推断类型?

来自分类Dev

编译器如何将Nullable <T>识别为“特殊类型”?

来自分类Dev

是否可以指示编译器删除C ++中返回的variant_t的副本?

来自分类Dev

在Vector实现中如何正确使用std :: allocator <T>

来自分类Dev

使用通用T确定编译器选择的过载

来自分类Dev

返回类型为“ <T扩展...>”的意外编译器警告

来自分类Dev

编译器选择错误的重载调用IEquatable <T> .Equals

来自分类Dev

使用通用T确定编译器选择的过载

来自分类Dev

单个路径的编译器错误读取[T]

来自分类Dev

编译器如何实现C ++继承?

来自分类Dev

GraalVM:如何实现编译器优化?

Related 相关文章

  1. 1

    队列数据结构中is_empty的线程安全实现

  2. 2

    .NET编译器如何为HashSet <T>中的任何T构造O(1)查找?

  3. 3

    如何在std :: atomic <T>上实现简单的自旋锁,以使编译器不会对其进行优化?

  4. 4

    如何在std :: atomic <T>上实现简单的自旋锁,以使编译器不会对其进行优化?

  5. 5

    无法在VS2015中禁用编译器警告

  6. 6

    Boost :: filesystem :: is_empty()为Symlinks返回false

  7. 7

    将is_empty添加到哈希表

  8. 8

    如何在VS2015中使用T4模板生成多个文件输出?

  9. 9

    尝试创建和使用一个类;未定义名称“ is_empty”

  10. 10

    如何使C ++编译器间接推导T?

  11. 11

    “无法将参数1从'Node <T>'转换为'std :: nullptr_t”编译器错误

  12. 12

    如何在VS2015中使用T4?(未找到Microsoft.TextTemplating.targets文件)

  13. 13

    使用VS2010编译器编译VS2015项目

  14. 14

    为什么VS 2015编译器无法在abs()实现中优化浮点数的分支?

  15. 15

    编译器在VS2015中显示“表达式必须具有恒定值”(C编程)

  16. 16

    禁用VS2015 C#编译器自动生成[Serializable]属性

  17. 17

    VS2015编译器将忽略对我的DLL的所有引用

  18. 18

    禁用VS2015 C#编译器自动生成[Serializable]属性

  19. 19

    Scala:如何让编译器从Seq [T]类型的函数参数推断类型?

  20. 20

    编译器如何将Nullable <T>识别为“特殊类型”?

  21. 21

    是否可以指示编译器删除C ++中返回的variant_t的副本?

  22. 22

    在Vector实现中如何正确使用std :: allocator <T>

  23. 23

    使用通用T确定编译器选择的过载

  24. 24

    返回类型为“ <T扩展...>”的意外编译器警告

  25. 25

    编译器选择错误的重载调用IEquatable <T> .Equals

  26. 26

    使用通用T确定编译器选择的过载

  27. 27

    单个路径的编译器错误读取[T]

  28. 28

    编译器如何实现C ++继承?

  29. 29

    GraalVM:如何实现编译器优化?

热门标签

归档