2017-03-10 15 views
0

テンプレートパラメータを使用しないテンプレートクラスのメソッドに対するコンパイラの最適化はありますか?例えば、

template< class T > 
class Foo 
{ 
public: 
    float MethodUseOfT() 
    { 
     return m_bar.CalculateSomething(); 
    } 
    float MethodNoUseOfT() 
    { 
     float blah(0.f); 
     ... 
     return blah; 
    } 

private: 
    T m_bar; 
}; 

class Bar 
{ 
public: 
    float CalculateSomething(); 
} 

誰かがFoo<Bar>を作成した場合、これはほとんどのコンパイラによってどのように管理されますか。たとえば、一般にMethodNoUseOfTがテンプレート引数を参照せず、その情報を使用して生成されたマシンコードのサイズを縮小することを実現するでしょうか?

さらに、MethodUseOfTの内容が大きく、1行にTを参照するだけの場合、コンパイラは残りのメソッドに対して生成されたマシンコードを再利用しようとしますか?

+0

私は 'MethodUseOfT'を実際に*使用していません*' T'?あるいは一般的に 'T 'の使用。 –

+1

あなたの問題に関しては、現代のコンパイラは、通常、最適化に関して非常に良いです。しかし、確かに知る唯一の方法は、実際に生成されたコードを調べることです。 –

+0

編集:ありがとうございます。申し訳ありませんが、m_barのタイプはTです。 –

答えて

0

多分。

Microsoft C++には、同じ機能をマージするオプションがあります(もちろん、Foo<int>::MethodNoUseOfT()Foo<double>::MethodNoUseOfT()と同じになります)。

一般的に、このオプションは標準に準拠していません(ファンクションテンプレートから生成される2つの通常のファンクションは、異なるアドレスを持つ必要があります。しかし、この場合は、メンバ関数のアドレスを取得する方法がないため(メンバ関数へのポインタがアドレスとは非常に異なり、アドレスよりはるかに複雑です)、リンカそれを行うことができるかもしれません。

コメントに記載されているように、コンパイラ+リンカの出力を検査することが唯一の唯一の方法です。

確認する簡単な方法は、のようなものを書くことです:

class FooBase 
{ 
public: 
    float MethodNoUseOfT() 
    { 
     float blah(0.f); 
     ... 
     return blah; 
    } 
}; 

template< class T > 
class Foo : public FooBase 
{ 
public: 
    float MethodUseOfT() 
    { 
     return m_bar.CalculateSomething(); 
    } 

private: 
    T m_bar; 
}; 

class Bar 
{ 
public: 
    float CalculateSomething(); 
} 

あなたがこれを行う場合は、あなたもCPPファイルにMethodNoUseOfTの実装を移動することができます。

0

インラインの場合のみ。さもなければ、シンボルはマングルされているので、それらは別個のマシンコードブロックでなければならない。

+0

明示的なインスタンス化を使用しない限り、テンプレートメンバー関数はかなり* *インライン化されています。 –

0

です。

重要な部分は、14.7.1暗黙のインスタンスです。関数定義を必要とするコンテキストで特殊化が参照されると、関数テンプレートの特殊化が暗黙的にインスタンス化されます。

つまり、暗黙的なインスタンス化では、実際には必ず「最適化」が必要です。明示的なインスタンス化では、コンパイラはすべてのメンバーをコンパイルします(結局のところ、明示的なインスタンス化のポイントです)。しかし、リンカはまだ未使用の機能を排除できます。

コンパイラは、テンプレートメソッドの半分を再利用しようとしません。それは非常に複雑な分析を必要とするでしょう。

関連する問題