133

テンプレートはヘッダー内で定義され、コンパイラーは関数のインライン化が有利かどうかを判断できるので、それは意味がありますか?最近のコンパイラは、関数をインライン化するタイミングをよく知っており、inlineヒントを無視していると聞きました。


編集:私は両方の答えを受け入れたいのですが、これは不可能です。問題を解決するために、私はセバスティアン・マッハの答えを受け入れています。なぜなら、それはほとんどの票を獲得し、彼は正式に正しいからですが、コメントで述べたように、私はパピーコンポーネント10の答えも正しいものだと考えています。見る。

問題はC++のセマンティクスにあり、inlineキーワードとインライン化の場合は厳密ではありません。セバスチャン・マッハは「あなたがそれを意味するならインラインで書く」と言いますが、パピーinlineが言うように、それが元の意味から「コンパイラがODR違反について愚痴を言うのを止める」という指令に進化したので、実際に何を意味するのかは明確ではありません。

4

4 に答える 4

105

それは無関係ではありません。いいえ、すべての関数テンプレートがinlineデフォルトであるわけではありません。この標準は、明示的な特殊化([temp.expl.spec])で明示されています。

次のものがあります。

a.cc

#include "tpl.h"

b.cc

#include "tpl.h"

tpl.h(明示的な特殊化から取得):

#ifndef TPL_H
#define TPL_H
template<class T> void f(T) {}
template<class T> inline T g(T) {}

template<> inline void f<>(int) {} // OK: inline
template<> int g<>(int) {} // error: not inline
#endif

これをコンパイルして、出来上がり:

g++ a.cc b.cc
/tmp/ccfWLeDX.o: In function `int g<int>(int)':
inlinexx2.cc:(.text+0x0): multiple definition of `int g<int>(int)'
/tmp/ccUa4K20.o:inlinexx.cc:(.text+0x0): first defined here
collect2: ld returned 1 exit status

明示的なインスタンス化を行うときに明記しないinlineことも、問題につながる可能性があります。

要約すると、完全に特殊化されていない関数テンプレート、つまり、少なくとも1つの不明なタイプを持つテンプレートの場合、を省略inlineしてエラーを受け取らないようにすることができますが、それでもエラーは発生しませんinline。完全な特殊化、つまり既知のタイプのみを使用する特殊化の場合、それを省略することはできません。

提案された経験則inlineあなたがそれを意味し、ただ一貫している場合は書いてください。それはあなたができるという理由だけで生きるべきかどうかについて考えることを少なくします。(この経験則は、Vandevoorde /JosuttisのC++テンプレート:完全ガイドに準拠しています)。

于 2012-05-10T14:49:32.377 に答える
41

それは無関係です。すべてのテンプレートはすでにありますinline-言うまでもなく、2012年の時点で、inlineキーワードの唯一の使用法は、コンパイラーがODR違反について不平を言うのを止めることです。あなたは絶対に正しいです-あなたの現世代のコンパイラはそれ自身で何をインライン化するかを知っており、おそらく翻訳ユニット間でもそうすることができます。

于 2012-05-10T14:05:07.153 に答える
7

あなたが提案したように、これinlineはコンパイラへのヒントであり、それ以上のものではありません。それを無視するか、実際、インラインとしてマークされていない関数をインライン化するかを選択できます。

テンプレートを使用inlineすることは、各コンパイルユニットが同じテンプレートクラスに対して個別のオブジェクトを作成し、リンク時に重複の問題を引き起こすという問題を回避するための(不十分な)方法でした。inline(私が思うに)名前マングリング  を使用することにより、リンク時の名前の衝突を回避するが、コードが大幅に肥大化するという犠牲を払って、異なる方法で機能します。

マーシャル・クラインは、私ができるよりもここでそれをよりよく説明しています。

于 2012-05-10T14:12:30.400 に答える
-2

これはC++標準が言っていることです:

[dcl.inline / 1]

インライン指定子は、変数または関数の宣言にのみ適用されます。

于 2020-10-22T20:08:24.837 に答える