我想用C ++生成具有唯一确定性名称的各种数据类型。例如:
struct struct_int_double { int mem0; double mem1; };
目前我的编译器使用计数器合成名称,这意味着在不同的翻译单元中编译相同的数据类型时名称不一致。
这是不起作用的:
使用ABI mangled_name函数。因为它已经取决于具有唯一名称的结构。通过假装struct是匿名的,可以在符合C ++ 11的ABI中工作吗?
模板,例如struct2,因为模板不适用于递归类型。
彻底破坏。因为它提供的名称太长(数百个字符!)
除了全局注册表(YUK!)之外,我唯一能想到的是首先创建一个唯一的长错位名称,然后使用摘要或哈希函数来缩短它(并希望没有冲突)。 / p>
实际问题:生成可以在类型为匿名的地方调用的库,例如元组,和类型,函数类型。
还有其他想法吗?
编辑:递归类型问题的加法描述。考虑定义一个这样的链表:
template<class T>
typedef pair<list<T>*, T> list;
这实际上是必需的。它不起作用有两个原因:首先,你不能模板化typedef。 [不,您不能使用带有typedef的模板类,它不起作用]其次,您不能将list *作为参数传递,因为它尚未定义。在没有多态性的C中,你可以这样做:
struct list_int { struct list_int *next; int value; };
有几种解决方法。对于这个特定的问题,您可以使用Barton-Nackman技巧的变体,但它没有概括。
有一个一般的解决方法,首先由Gabrielle des Rois向我展示,使用带有开放递归的模板,然后使用部分特化来关闭它。但这很难产生,即使我能弄清楚如何去做也可能是不可读的。
还有另一个问题正确地做变种,但这并不是直接相关的(由于对使用可构造类型声明联合的愚蠢限制,情况更糟)。
因此,我的编译器只使用普通的C类型。无论如何,它必须处理多态性:编写它的原因之一是绕过包含模板的C ++类型系统的问题。这会导致命名问题。
答案 0 :(得分:1)
你真的需要同意的名字吗?只需在不同的翻译单元中单独定义具有不同名称的结构,并在必要时reinterpret_cast<>
以保持C ++编译器满意。当然,这在手写代码中是可怕的,但这是由编译器生成的代码,因此您可以(并且我假设)在生成C ++代码之前执行必要的静态类型检查。
如果我错过了某些内容并且您确实需要类型名称同意,那么我认为您已经回答了自己的问题:除非编译器可以在多个翻译单元的翻译之间共享信息(通过某些全局注册表),我看不出有什么方法可以从类型的结构形式生成唯一的,确定性的名称,除了明显的名称修改之外。
至于姓名的长短,我不确定为何重要?如果您正在考虑使用哈希函数缩短名称,那么显然您不需要它们是人类可读的,那么为什么它们需要简短呢?
就我个人而言,我可能会生成半人类可读的名称,其风格与现有的名称修改方案类似,而且不需要使用哈希函数。因此,不是生成struct_int_double
,而是生成sid
(struct,int,double)或si32f64
(struct,32位整数,64位浮点数)等等。这样的名称的优点是它们仍然可以直接解析(这似乎对于调试来说非常重要)。
修改强>
更多想法:
编辑2:抱歉,大脑失败 - sha-1摘要是160位,而不是128位。
PS。不知道为什么这个问题被拒绝了 - 这对我来说似乎是合理的,尽管你正在研究的关于这个编译器的更多上下文可能有所帮助。
答案 1 :(得分:0)
我真的不明白你的问题。
template<typename T>
struct SListItem
{
SListItem* m_prev;
SListItem* m_next;
T m_value;
};
int main()
{
SListItem<int> sListItem;
}