C++ 为什么';tc++;使对类型进行编译时查询变得更容易?

C++ 为什么';tc++;使对类型进行编译时查询变得更容易?,c++,templates,c++11,generic-programming,sfinae,C++,Templates,C++11,Generic Programming,Sfinae,我刚刚开始学习模板元编程技巧,它允许您查询类型 例如,允许我们通过使用重载和返回类型sizeof comparison来检查类型在编译时是否具有特定的typedef或函数 Q:那么,为什么(如果C++11/14中有更好的方法,请纠正我的错误)该语言不提供更好的机制/接口来进行有关类型的查询呢 编辑:我想澄清一下,这不是咆哮(如果听起来是这样,我很抱歉)。因为我才刚刚开始意识到模板的威力,所以我想确保我的思维过程不会混乱 对于我要进行这些查询的每个模板类/函数,我必须创建一个特定于SFINAE的版

我刚刚开始学习模板元编程技巧,它允许您查询类型

例如,允许我们通过使用重载和返回类型sizeof comparison来检查类型在编译时是否具有特定的typedef或函数

Q:那么,为什么(如果C++11/14中有更好的方法,请纠正我的错误)该语言不提供更好的机制/接口来进行有关类型的查询呢

编辑:我想澄清一下,这不是咆哮(如果听起来是这样,我很抱歉)。因为我才刚刚开始意识到模板的威力,所以我想确保我的思维过程不会混乱

对于我要进行这些查询的每个模板类/函数,我必须创建一个特定于SFINAE的版本。问编译器“没有名为
a
的成员”或“没有名为
(arg list)
的函数”的单一接口不是一种更简洁的方法吗?当然,编译器拥有与用户定义类型相关的所有知识——它只需要将这些知识公开给程序员进行编译时查询


Q:依赖这种通用功能是设计/思考模板的一种糟糕方式吗?如果是这样的话,请说明你的理由(如果可能的话,请举例说明不需要查询就可以完成任务)。

SFINAE tricks&co.的Template metaprogramming实际上并不是为完成这项任务而设计的。在C++中发现模板元程序设计。 模板的开始只是为了编写类型通用代码,增加了更多功能以覆盖各种情况(SFINAE的诞生是为了避免在同一程序中拉取不相关模板时可能发生的编译器错误),有一天,有人发现C++模板提供了一个图灵完整的元语言,允许执行关于类型的查询,在编译时执行计算等。 <> P> >,C++中的模板元编程是难懂的、难于写的、难于调试的、难以编译的,因为它主要是对其他用途的滥用。模板恰巧是如此强大,但实际上没有人为此设计模板

C++11为这种用法提供了一些库支持(以及一些核心语言支持),但这并没有改变这种情况的本质


另外,如果你想听听我的意见,模板元编程目前被严重滥用;有了它,你可以构建像Boost.Spirit这样的怪物,但你可能不应该这样做。

SFINAE感觉像是一个黑客,因为它是。你想做的是反思

一开始听起来很简单,但基本问题在于一个简单的问题:如何知道任意对象是什么类型

在具有VM/运行时的语言中,它知道曾经创建的每个对象,这可以通过直接询问运行时/VM来解决。在C++模板中,它提供了一个逃生路径,因为在某个时刻必须实例化模板。在实例化时,编译器必须知道类型。SFINAE的基本目标是在编译时捕获这些知识,并将其重新用于编码指令,当在运行时进行评估时,这些指令将产生正确的结果,以确定实例化模板的类型

SimeAe也恰好不需要在“普通”C++模板之上实际上没有额外的机器,编译器最初不需要实现。


为了在编译时进行适当的反射而不使用SFINAE之类的技巧,对于没有外部依赖关系的静态链接程序,您只需解决停止问题。这是明智的人、编译器作者甚至语言委员会非常希望避免的事情

为了在一般情况下做到这一点,包括您编写库代码,这些代码将来将作为DSO由其他代码链接。。。好吧,你必须做时间旅行到未来,只是为了检查未来的代码。所以是的,这是不可能的


因此,您需要有关类型和方法的适当运行时信息,以便执行真正想要执行的操作。但是SFINAE允许您使用快捷方式,因为您可以使用在实例化时传递类型的事实来提取信息,使用模板中的类型变量和编译时sizeof求值将编译时类型变量导出为生成代码中的常量,作为模板实例化的副作用。如前所述,它感觉像黑客的原因是因为它是黑客。

我不认为这个问题仅仅是一个含蓄的咆哮。它只能征求意见。投票结束。亲爱的斯特劳斯塔普…@johndilling-我不同意。我试图找出我对模板编程的总体想法是否“错了”。您可能对当前的两个研究小组感兴趣:SG7反思和SG8概念。@Raja:很公平。如果你能把这个问题重新组织起来,让它看起来不像一个咆哮,我会很高兴收到我的投票关闭,或者投票重新打开,如果它走得那么远。是的,这很好地解释了,我觉得c++11语言标准是从什么演变而来的……我对其他编译语言很好奇。他们有语言构造来与编译器交互吗?大多数情况下,附加的兴趣点是C++中的类型也被滥用在模板中,目的是为了它们没有被设计的目的。您真正想要的是Haskell或类似的类型类,它们表示对象的特定接口。不同之处在于类型类对任何层次结构或类似结构都不作任何假设,它们纯粹是一种编译时契约,类似于Java接口。@Raja的设计初衷就是要这样。“为了在编译时进行适当的反射而不使用SFINAE之类的技巧,对于没有外部依赖关系的静态链接程序,您只需要解决停止问题。”这只是一个问题