在运行时修改模板函数的名称 - 可能吗?
Mangling names for templated functions in runtime - possible?
假设我写了一个 foo<T>
函数(我有一个带命名空间的完整签名),但现在不用管它了);并假设没有其他函数重载它(在它所在的相关命名空间中)。现在让我们将自己置于运行时。假设我有字符串 "foo",对于某些类型 MyType
,我有 typeid(MyType)
(来自 <memory>
header)。
我能以某种方式获得 foo<MyType>
的符号 name 吗?
这个问题的第二个版本:现在假设我有 foo 的完整签名作为一个字符串,而不仅仅是名字;并放弃关于没有超载的假设。
备注:
- 不,我问的不是符号本身,只是名称。这将是另一个有趣的问题。
- 依赖于来自共享库的
foo<T>
的答案是相关的,尽管我认为它不应该只对符号 name.[=34 重要=]
- 我不在乎这里的性能,我会做任何事情。帮助我 Obi Wan,你是我最后的希望等等。所以,RTTI,用奇怪的标志编译,随便什么。
- Platform-dependent 答案也是相关的: GNU/Linux with kernel version >= 3.x , an x86_64 CPU , gcc >= 4.8 .
不,你不能。
要获取实例化函数模板的错位名称,在最简单的情况下,您需要以下信息:
- 函数的完全限定名(你说你只有
"foo"
,如果函数在命名空间中怎么办?)
- 所有模板类型参数的类型(类型的修饰名称 可能 就足够了,如果函数名称的修饰方案直接嵌入类型名称;否则你会需要完整的类型名称,可能递归到该类型的所有模板参数中。
- 所有函数参数的类型(同样适用)。
这是假设您没有模板模板参数或非类型参数。当你拥有这些时,它会变得更加复杂,因为它可能需要整个表达式树的损坏形式。它还假定您不处理部分或完全显式专业化,这更加复杂。最后假设您的函数由于特定于编译器的扩展而没有任何特殊修饰(例如 __stdcall
在 32 位 Windows 环境中)。哦,一些 ABI 也可能对函数的 return 类型进行编码。
因为根据你的前提你只有函数名(不清楚是否完全合格)和模板参数的type_id对象(可能 作为错位类型名称的来源,但不是在所有平台上),您没有足够的信息来重新创建错位名称。
这留下了从二进制文件中获取所有已编译符号列表的选项(如果可用)并搜索最有可能的候选者,这当然容易出错。
假设我写了一个 foo<T>
函数(我有一个带命名空间的完整签名),但现在不用管它了);并假设没有其他函数重载它(在它所在的相关命名空间中)。现在让我们将自己置于运行时。假设我有字符串 "foo",对于某些类型 MyType
,我有 typeid(MyType)
(来自 <memory>
header)。
我能以某种方式获得 foo<MyType>
的符号 name 吗?
这个问题的第二个版本:现在假设我有 foo 的完整签名作为一个字符串,而不仅仅是名字;并放弃关于没有超载的假设。
备注:
- 不,我问的不是符号本身,只是名称。这将是另一个有趣的问题。
- 依赖于来自共享库的
foo<T>
的答案是相关的,尽管我认为它不应该只对符号 name.[=34 重要=] - 我不在乎这里的性能,我会做任何事情。帮助我 Obi Wan,你是我最后的希望等等。所以,RTTI,用奇怪的标志编译,随便什么。
- Platform-dependent 答案也是相关的: GNU/Linux with kernel version >= 3.x , an x86_64 CPU , gcc >= 4.8 .
不,你不能。
要获取实例化函数模板的错位名称,在最简单的情况下,您需要以下信息:
- 函数的完全限定名(你说你只有
"foo"
,如果函数在命名空间中怎么办?) - 所有模板类型参数的类型(类型的修饰名称 可能 就足够了,如果函数名称的修饰方案直接嵌入类型名称;否则你会需要完整的类型名称,可能递归到该类型的所有模板参数中。
- 所有函数参数的类型(同样适用)。
这是假设您没有模板模板参数或非类型参数。当你拥有这些时,它会变得更加复杂,因为它可能需要整个表达式树的损坏形式。它还假定您不处理部分或完全显式专业化,这更加复杂。最后假设您的函数由于特定于编译器的扩展而没有任何特殊修饰(例如 __stdcall
在 32 位 Windows 环境中)。哦,一些 ABI 也可能对函数的 return 类型进行编码。
因为根据你的前提你只有函数名(不清楚是否完全合格)和模板参数的type_id对象(可能 作为错位类型名称的来源,但不是在所有平台上),您没有足够的信息来重新创建错位名称。
这留下了从二进制文件中获取所有已编译符号列表的选项(如果可用)并搜索最有可能的候选者,这当然容易出错。