7

非テンプレート クラスにメンバ関数テンプレートがあり、それをクラス外で定義したい場合、「インライン」を使用する必要がありますか?

例:

class A
{
    template <class D>
    void someMethod(D param);
}

template <class D>
/* inline needed here? */ void A::someMethod(D param)
{
}

標準のセクション 3.2.5 は、関数テンプレートは 1 つの定義規則に該当しないと述べています。この点で、メンバー関数テンプレートは関数テンプレートですか?

編集:リンカーはインラインなしで文句を言いませんが、それでも有効な C++03 ですか?

編集:

これまでに学んだこと: gcc (およびおそらく他のコンパイラも) は、暗黙的なテンプレートのインスタンス化をウィークシンボルとしてエクスポートします。つまり、複数の翻訳単位でインスタンス化されている場合、リンク時に競合は発生しません。弱いシンボルは標準の一部ではないため、標準ではテンプレートのインスタンス化がこのように動作することを暗黙のうちに要求していますか?他の標準準拠のコンパイラ/リンカーの組み合わせで同じ動作を期待できますか?

インラインは最適化のために基本的に無視されますが、異なる翻訳単位で関数の複数の定義を許可するため、これは暗黙的にこれらの関数を弱いシンボルとしてエクスポートすることに変換されますこれは、テンプレートをインラインとして宣言することは冗長であることを意味しますか?

4

2 に答える 2

0

inlineキーワードは、そのようにマークされた関数が同じ名前を持つ最適化の適切な候補であることをコンパイラーに示唆するためのものであり、そのような最適化を実装するための助けとして、関数を定義することを義務付けています-同じ方法で- - それが使用されている各 CU で (リンカーが同じ最適化を行うことができたとしても、コンパイラがコードを見れば最適化を行うのははるかに簡単ですが、20 年前にははるかに一般的ではありませんでした)。

関数テンプレートにこのヒントを与えて、関数テンプレート定義をインラインでマークすることができます。そのヒントを与えたくない場合は、インラインは必要ありません。

(インラインでマークされた関数のみが最適化のために考慮されていた時期がありましたが、キーワードはまだ運命を満たしていませんregister。つまり、変数のアドレスを取得することを防ぐという正式な意味を除いて、一般的にコンパイラによって無視されています。 )。

于 2012-10-02T13:36:30.440 に答える
0

メンバー関数テンプレートが関数テンプレートであるかどうかにかかわらず、それらは確かにオブジェクトまたは非インライン関数ではないため、1 つの定義ルールは適用されません。

しかし、それらは実際には関数テンプレートであり、非メンバー関数テンプレートに固有ではない標準の他のアプリケーションではそのようにカウントされます。

于 2012-10-02T13:26:41.960 に答える