我的意思是我们如何从某些模板T add(T a, T b) ...
进入生成的代码?我已经想到了几种方法来实现,我们将通用函数存储在AST中Function_Node
,然后每次使用它时,都会在原始函数节点中存储其自身的副本,其中所有类型都T
替换为正在使用。例如add<int>(5, 6)
将存储的通用功能的副本add
并替换所有类型T
的副本有int
。
所以它看起来像:
struct Function_Node {
std::string name; // etc.
Type return_type;
std::vector<std::pair<Type, std::string>> arguments;
std::vector<Function_Node> copies;
};
然后,您可以为这些代码生成代码,并在访问Function_Node
副本列表所在的位置时copies.size() > 0
调用visitFunction
所有副本。
visitFunction(Function_Node& node) {
if (node.copies.size() > 0) {
for (auto& node : nodes.copies) {
visitFunction(node);
}
// it's a generic function so we don't want
// to emit code for this.
return;
}
}
这会很好吗?现代编译器如何解决这个问题?我认为,执行此操作的另一种方法可能是,您可以将副本注入AST,以便它贯穿所有语义阶段。我还认为也许您可以立即生成它们,例如Rust的MIR或Swifts SIL。
我的代码是用Java编写的,这里的示例是C ++,因为示例的冗长程度有所降低-但原理基本上是相同的。尽管可能会出现一些错误,因为它只是在问题框中手动写出的。
请注意,我的意思是说现代编译器是解决此问题的最佳方法。当我说泛型时,我的意思不是像Java泛型那样使用类型擦除。