草庐IT

c++ - 没有编译器 Hook ,哪些<type_traits>无法实现?

coder 2023-05-03 原文

C++ 11提供了标准的<type_traits>

没有编译器挂钩,它们中的哪一个是不可能实现的?

  • 注1:通过编译器挂钩,我指的是任何非标准语言功能,例如__is_builtin...
  • 注2:许多方法可以不使用钩子(Hook)来实现(请参见C++ Template Metaprogramming的第2章和/或Modern C++ Design的第2章)。
  • 注3:上一个问题中的spraff answer引用了N2984,其中某些类型特征包含以下注解:被认为需要编译器支持(感谢sehe)。
  • 最佳答案

    我已经写了一个完整的答案here-这项工作仍在进行中,因此即使我将文本剪切并粘贴到此答案中,我也会提供权威的超链接。

    另请参见libc++的Type traits intrinsic design文档。

    is_union
    is_union查询未通过任何其他方式公开的类的属性;
    在C++中,您可以使用类或结构进行的任何操作,也可以使用联合进行的操作。这个
    包括继承和获取成员指针。

    is_aggregate,is_literal_type,is_pod,is_standard_layout,has_virtual_destructor

    这些特征查询未通过任何其他方式公开的类的属性。
    本质上,结构或类是“黑匣子”。 C++语言使我们无法
    将其打开并检查其数据成员,以了解它们是否都是POD类型,或者是否
    它们中的任何一个都是private,或者该类具有任何constexpr构造函数(键is_literal_type的要求)。

    is_abstract
    is_abstract是一个有趣的案例。摘要的定义特征
    类类型是您无法获得该类型的值;所以例如
    格式不正确,以定义其参数或返回类型为抽象的函数,并且
    创建元素类型为抽象的数组类型的格式不正确。
    (奇怪的是,如果T是抽象的,那么SFINAE将适用于T[],而不适用于T()
    是否可以使用抽象的返回类型创建函数的类型;
    定义这种功能类型的实体格式不正确。)

    因此,我们可以使用以下方法非常接近is_abstract的正确实现
    这种SFINAE方法:

    template<class T, class> struct is_abstract_impl : true_type {};
    template<class T> struct is_abstract_impl<T, void_t<T[]>> : false_type {};
    
    template<class T> struct is_abstract : is_abstract_impl<remove_cv_t<T>, void> {};
    

    但是,有一个缺陷!如果T本身是模板类,例如vector<T>basic_ostream<char>,那么仅形成T[]类型是可以接受的;在
    未评估的上下文,这将不会导致编译器实例化T的主体,因此编译器将不会检测到
    数组类型T[]。因此,在那种情况下SFINAE不会发生,我们将
    is_abstract<basic_ostream<char>>给出错误的答案。

    在未评估的上下文中进行模板实例化的唯一原因是
    现代编译器提供__is_abstract(T)

    is_final
    is_final查询未通过任何其他方式公开的类的属性。
    具体来说,派生类的基本说明符列表不是SFINAE上下文。我们不能
    利用enable_if_t询问“我可以创建一个从T派生的类吗?”因为如果我们
    无法创建这样的类,这将是一个很难的错误。

    是空的
    is_empty是一个有趣的案例。我们不能只问是否是sizeof (T) == 0,因为
    在C++中,不允许类型的大小为0;即使是一个空类也有sizeof (T) == 1
    但是,由于“空基数”的存在,“空虚”的重要性足以使其具有类型特征
    优化:所有足够现代的编译器都会布局这两个类
    struct Derived : public T { int x; };
    
    struct Underived { int x; };
    

    同样也就是说,他们不会在Derived中为空白留出任何空间T子对象。这表明我们至少可以在C++ 03中测试“空”的方法
    在所有足够现代的编译器上:只需定义以上两个类并询问
    是否sizeof (Derived) == sizeof (Underived)。不幸的是,从C++ 11开始,
    技巧不再起作用,因为T可能是最终的,并且该类的“最终性”
    类型不会通过其他任何方式公开!因此实现final的编译器供应商
    还必须公开类似__is_empty(T)的内容,以使标准库受益。

    is_enum
    is_enum是另一个有趣的情况。从技术上讲,我们可以实现这种类型特征
    通过观察,如果我们的T类型不是基本类型,即数组类型,
    指针类型,引用类型,成员指针,类或联合或函数
    类型,然后通过消除过程,它必须是枚举类型。但是,这种演绎
    如果编译器碰巧支持任何其他类型,则推理失败
    归入以上类别。因此,现代编译器公开__is_enum(T)

    不属于以上任何类别的受支持类型的常见示例
    将是__int128_t。 libc++实际上检测到__int128_t的存在并包括
    归类为“整体类型”(在上面将其称为“基本类型”
    分类),但我们的简单实现则没有。

    另一个示例是vector int,它支持Altivec vector 扩展。
    这种类型显然更“不完整”,但也“别无其他”,而且大多数
    当然不是枚举类型!

    is_trivially_constructible,is_trivially_assignable

    构造,分配和破坏的琐碎性都是
    没有通过其他任何方式公开的类。注意,有了这个基础
    我们不需要任何额外的魔术来查询默认构造的琐碎性,
    复制构造,移动任务等。代替,is_trivially_copy_constructible<T>在以下方面实现is_trivially_constructible<T, const T&>,依此类推。

    is_trivially_destructible

    由于历史原因,此内置编译器的名称不是__is_trivially_destructible(T)而是__has_trivial_destructor(T)。此外,事实证明内置
    即使对于具有删除的析构函数的类类型,其计算结果也为true!所以我们首先需要
    检查类型是否可破坏;然后,如果可以,我们可以询问内置的魔术
    那个破坏者是否确实微不足道。

    底层类型

    枚举的基本类型不会通过任何其他方式公开。你可以靠近
    通过获取sizeof(T)并将其与所有已知类型的大小进行比较,并询问
    通过T(-1) < T(0)获得底层类型的签名;但是这种方法仍然
    无法区分基础类型intlong在平台上的类型
    类型具有相同的宽度(在那些类型的平台上,longlong long之间也不相同)
    类型具有相同的宽度)。

    关于c++ - 没有编译器 Hook ,哪些<type_traits>无法实现?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20181702/

    有关c++ - 没有编译器 Hook ,哪些<type_traits>无法实现?的更多相关文章

    1. ruby - 难道Lua没有和Ruby的method_missing相媲美的东西吗? - 2

      我好像记得Lua有类似Ruby的method_missing的东西。还是我记错了? 最佳答案 表的metatable的__index和__newindex可以用于与Ruby的method_missing相同的效果。 关于ruby-难道Lua没有和Ruby的method_missing相媲美的东西吗?,我们在StackOverflow上找到一个类似的问题: https://stackoverflow.com/questions/7732154/

    2. ruby-on-rails - 如何从 format.xml 中删除 <hash></hash> - 2

      我有一个对象has_many应呈现为xml的子对象。这不是问题。我的问题是我创建了一个Hash包含此数据,就像解析器需要它一样。但是rails自动将整个文件包含在.........我需要摆脱type="array"和我该如何处理?我没有在文档中找到任何内容。 最佳答案 我遇到了同样的问题;这是我的XML:我在用这个:entries.to_xml将散列数据转换为XML,但这会将条目的数据包装到中所以我修改了:entries.to_xml(root:"Contacts")但这仍然将转换后的XML包装在“联系人”中,将我的XML代码修改为

    3. ruby-on-rails - Rails 3.2.1 中 ActionMailer 中的未定义方法 'default_content_type=' - 2

      我在我的项目中添加了一个系统来重置用户密码并通过电子邮件将密码发送给他,以防他忘记密码。昨天它运行良好(当我实现它时)。当我今天尝试启动服务器时,出现以下错误。=>BootingWEBrick=>Rails3.2.1applicationstartingindevelopmentonhttp://0.0.0.0:3000=>Callwith-dtodetach=>Ctrl-CtoshutdownserverExiting/Users/vinayshenoy/.rvm/gems/ruby-1.9.3-p0/gems/actionmailer-3.2.1/lib/action_mailer

    4. ruby-on-rails - rails 目前在重启后没有安装 - 2

      我有一个奇怪的问题:我在rvm上安装了ruby​​onrails。一切正常,我可以创建项目。但是在我输入“railsnew”时重新启动后,我有“程序'rails'当前未安装。”。SystemUbuntu12.04ruby-v"1.9.3p194"gemlistactionmailer(3.2.5)actionpack(3.2.5)activemodel(3.2.5)activerecord(3.2.5)activeresource(3.2.5)activesupport(3.2.5)arel(3.0.2)builder(3.0.0)bundler(1.1.4)coffee-rails(

    5. ruby-on-rails - 如何优雅地重启 thin + nginx? - 2

      我的瘦服务器配置了nginx,我的ROR应用程序正在它们上运行。在我发布代码更新时运行thinrestart会给我的应用程序带来一些停机时间。我试图弄清楚如何优雅地重启正在运行的Thin实例,但找不到好的解决方案。有没有人能做到这一点? 最佳答案 #Restartjustthethinserverdescribedbythatconfigsudothin-C/etc/thin/mysite.ymlrestartNginx将继续运行并代理请求。如果您将Nginx设置为使用多个上游服务器,例如server{listen80;server

    6. ruby - 在没有 sass 引擎的情况下使用 sass 颜色函数 - 2

      我想在一个没有Sass引擎的类中使用Sass颜色函数。我已经在项目中使用了sassgem,所以我认为搭载会像以下一样简单:classRectangleincludeSass::Script::FunctionsdefcolorSass::Script::Color.new([0x82,0x39,0x06])enddefrender#hamlengineexecutedwithcontextofself#sothatwithintemlateicouldcall#%stop{offset:'0%',stop:{color:lighten(color)}}endend更新:参见上面的#re

    7. ruby-on-rails - rspec should have_select ('cars' , :options => ['volvo' , 'saab' ] 不工作 - 2

      关闭。这个问题需要detailsorclarity.它目前不接受答案。想改进这个问题吗?通过editingthispost添加细节并澄清问题.关闭8年前。Improvethisquestion在首页我有:汽车:VolvoSaabMercedesAudistatic_pages_spec.rb中的测试代码:it"shouldhavetherightselect"dovisithome_pathit{shouldhave_select('cars',:options=>['volvo','saab','mercedes','audi'])}end响应是rspec./spec/request

    8. ruby-on-rails - Nokogiri:使用 XPath 搜索 <div> - 2

      我使用Nokogiri(Rubygem)css搜索寻找某些在我的html里面。看起来Nokogiri的css搜索不喜欢正则表达式。我想切换到Nokogiri的xpath搜索,因为这似乎支持搜索字符串中的正则表达式。如何在xpath搜索中实现下面提到的(伪)css搜索?require'rubygems'require'nokogiri'value=Nokogiri::HTML.parse(ABBlaCD3"HTML_END#my_blockisgivenmy_bl="1"#my_eqcorrespondstothisregexmy_eq="\/[0-9]+\/"#FIXMEThefoll

    9. 没有类的 Ruby 方法? - 2

      大家好!我想知道Ruby中未使用语法ClassName.method_name调用的方法是如何工作的。我头脑中的一些是puts、print、gets、chomp。可以在不使用点运算符的情况下调用这些方法。为什么是这样?他们来自哪里?我怎样才能看到这些方法的完整列表? 最佳答案 Kernel中的所有方法都可用于Object类的所有对象或从Object派生的任何类。您可以使用Kernel.instance_methods列出它们。 关于没有类的Ruby方法?,我们在StackOverflow

    10. ruby-on-rails - Rails 3,嵌套资源,没有路由匹配 [PUT] - 2

      我真的为这个而疯狂。我一直在搜索答案并尝试我找到的所有内容,包括相关问题和stackoverflow上的答案,但仍然无法正常工作。我正在使用嵌套资源,但无法使表单正常工作。我总是遇到错误,例如没有路线匹配[PUT]"/galleries/1/photos"表格在这里:/galleries/1/photos/1/edit路线.rbresources:galleriesdoresources:photosendresources:galleriesresources:photos照片Controller.rbdefnew@gallery=Gallery.find(params[:galle

    随机推荐