ここで私が意味しているのは、テンプレートから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ジェネリックのような意味ではありません。