2017-02-03 17 views
1

関数が呼び出されていない場合、llvmに存在する他のタイプの関数(int、float ...)とは異なり、LLVM IRをC++コードから出力すると、テンプレート関数がLLVM-IRに表示されないのはなぜですか? IR 例:以下の関数func1 doesntのショーLLVM IRにテンプレート機能がLLVM-IRに表示されないのはなぜですか?

template <class tmp> 
tmp func1() { 
    // ... 
} 

しかし、この機能func2は常に

int func2() { 
    // ... 
} 
+1

これは*テンプレート関数*ではありません。これは*関数テンプレート*です。これは機能ではなく、将来の機能の青写真です。それは完全に重要ではありません。'func 'は*テンプレート関数*、つまりすべてのテンプレートパラメータが既に分かっている*関数テンプレート*になります。これは*テンプレートをインスタンス化して、 "マテリアライズ"させます。 – AnT

答えて

5

IR LLVMに示しこれがあることですテンプレートは関数ではないため、関数テンプレートです。それらは議論でインスタンス化されるまでは結果ではありません。たとえば、次のコードを使用します。

template<typename T> 
T foo() { /* ... */ } 

これはコードの出力も出力もしません。

しかし、この一方で:

template<typename T> 
T foo() { /* ... */ } 

int test() { 
    return foo<int>(); 
} 

ウィル出力testfoo<int>の両方のためのコード。これはhow C++ templates workに関係している

template int foo<int>(); 
4

は手動でも、このようなテンプレートをインスタンス化することができます。コンパイラは関数を呼び出す(正確にはインスタンス化する)まで、tmpが何であるかを知らないので、コードを書く方法を知らない。たとえば、このテンプレートを考えてみましょう。Tが整数の場合

template <typename T> 
T add(T left, T right) { 
    return left + right; 
} 

、その後、関数本体は、整数のアドオンです。 Tがdoubleなら、浮動小数点加算です。 Tstd::stringの場合は、std::string::operator+の関数呼び出しです。

C++プログラムには多くの型があり、多くは追加できますが、ほとんどすべてが異なる方法で追加されます。この型を知るまで、関数のコードを作成することはできません。すべての可能なタイプTのためにそれをしようとすると、ほとんどすべてが使用されない可能性のある実装の組み合わせの爆発を得るでしょう。あなたのコンパイル時間とバイナリサイズは、もしあれば少しでも大きなものになります。


class templatesでは少し複雑になります。クラステンプレートのインスタンス化は、呼び出されていなければ実際にすべての関数をインスタンス化する必要はありません。私たちが代わりに書いてあれば、私たちの例に戻って:コンパイラはadd<int>が潜在的に興味深いであることを知っているすべての情報を持っているにもかかわらず、あなたが実際にがないので

template <typename T> 
class Adder { 
    T add(T left, T right) { 
     return left + right; 
    } 
}; 

Adder<int> a; 

このまだは、Adder<int>::addをインスタンス化しませんはそれを呼び出したり、インスタンス化したりします。

関連する問題