C++ 类型的编译时排序

C++ 类型的编译时排序,c++,C++,我一直在寻找一种在编译时获得类型排序的方法。例如,这对于实现(高效的)编译时类型集非常有用 一个显而易见的方法是,如果有一种方法可以将每种类型映射到一个唯一的整数。关于该主题的答案简明扼要地说明了为什么这很困难,并且似乎它同样适用于任何其他尝试获得订单的方式: 编译器无法知道所有编译单元,链接器也没有类型的概念 事实上,编译器面临的挑战是相当大的:它必须确保在任何调用中,对于任何源文件,它为给定类型返回相同的整数/它在任何两个给定类型之间返回相同的顺序,但同时,类型的宇宙是开放的,它不知道当前文

我一直在寻找一种在编译时获得类型排序的方法。例如,这对于实现(高效的)编译时类型集非常有用

一个显而易见的方法是,如果有一种方法可以将每种类型映射到一个唯一的整数。关于该主题的答案简明扼要地说明了为什么这很困难,并且似乎它同样适用于任何其他尝试获得订单的方式:

编译器无法知道所有编译单元,链接器也没有类型的概念

事实上,编译器面临的挑战是相当大的:它必须确保在任何调用中,对于任何源文件,它为给定类型返回相同的整数/它在任何两个给定类型之间返回相同的顺序,但同时,类型的宇宙是开放的,它不知道当前文件之外的任何类型。一个难题

我的想法是类型有名称。根据C++的规则,我知道,在整个程序中,一个类型的完全限定名必须是唯一的,否则会得到某种或其他错误或未定义的行为。
  • 如果两种类型具有相同的名称,则它们是相同的类型

  • 如果两个类型是相同的类型,那么它们要么具有相同的名称,要么是彼此的typedef。编译器完全了解typedef

名称是字符串,字符串具有顺序。因此,如果我没有弄错的话,您可以根据类型的名称定义一个全局一致的排序。更具体地说,任何两个类型之间的排序都是typedef完全解析的类型名称之间的排序。(让一个类型的行为与其typedefs不同会有问题。)


当然,标准C++没有任何类型的检索工具。

我的问题是:

  • 我有什么问题吗?从理论上讲,这有什么理由不起作用吗

  • 有没有编译器可以让您在编译时作为语言扩展访问类型名称(最好是它们的typedef解析形式)

  • 还有别的办法吗?有什么编译器可以这样做吗

(我承认在同一个问题中问多个问题是不礼貌的,但在三个独立的问题前面贴上相同的基本清嗓子似乎很奇怪。)

类型的完全限定名在整个程序中必须是唯一的

当然,如果在不同的翻译单位中考虑不同的匿名名称在某种意义上具有不同的名称,并且有某种方法来确定它们是什么,那么这是唯一的。 我唯一能感觉到他们确实有不同的名字是在损坏的链接器符号中;您可能(取决于编译器)能够从
type_info::name()
中获得该值,但不能保证它仅限于使用RTTI的类型,而且无论如何似乎都不会声明为
constepr
,因此您不能在编译时使用该值

type_info::before()
生成的排序自然也有相同的限制


兴趣之外,你用编译时类型排序来实现什么?

我怀疑你使用的是错误的编程语言。(而且,FWW,我认为你的问题分组在这种情况下可能是好的。它们是紧密顺序的)。“当然,标准C++没有任何类型来检索类型的名称。”-我也尝试在C++中实现类型排序,看起来在标准C++中是不可能的。有人可能会编写一个GCC插件来实现这一点,但我还没有尝试。@FailedDev这是一个运行时工具,不是编译时工具。匿名名称空间!很好。我忘了。请注意,在我的问题中,完全限定名的功能不一定是直接公开它们,而是(假设)作为一种机制,在类型上实现一致的编译时顺序。为此(如果我的想法正确的话)我们把它们放在订单的哪个位置几乎无关紧要,只要它们是一致的。关于type_info::name(),不幸的是,typeid操作符本身不是constexpr,因此这并不能让我们走得更远。至于我的用例:我想实现一个记录类型系统,其中“字段标签”可以在记录类型之间共享。但记录中字段的顺序应该无关紧要。字段标签的“名称”由虚拟类型表示。在实践中,您必须以某种顺序写下它们,但Record应该与Record完全互操作。因此,类型的行为应该更像一个集合,而不是一个列表。对于实现一个您更希望使用运算符的集合(而且,我完全忘记了另一件事,那就是type_info::before()。我的出发点更多的是GHC/Haskell实现其可类型类的方式。但是如果type id和type_info::before()是constexpr(有可能在运行时实现它们,但不会在编译时吗?)这基本上解决了我的愿望。)使用递归定义的模板有可能获得更容易的类型索引字段访问。我认为这是在现代C++设计中描述的,但如果需要的话,我明天会把它编辑成我的答案。(您的记录本质上是一个精巧的元组)。类型索引字段访问不是问题,我不需要类型级别的类型排序。(我确实将使用递归定义的模板,是的,它确实是一个精巧的元组——事实上,“普通”元组可能就是实现所要使用的。)不那么简单的是复制构造函数、赋值运算符等,它们应该与类型模板参数的顺序无关。(如果我对类型有一个顺序,我总是可以将它们按某种规范顺序排列,而不是按某种顺序排列。)