1. ホーム
  2. c++

[解決済み] ODR-use "とは?

2022-12-07 02:50:38

質問

これは、ちょうど以下の文脈で出てきたものです。 別の質問 .

どうやらクラステンプレート内のメンバー関数は、ODRが使用されている場合にのみインスタンス化されるようです。 誰かそれが正確に何を意味するのか説明してください。その wikipedia の One Definition Rule (ODR) に関する記事 は " に触れていません。 ODR の使用 について言及していません。

しかし、規格では次のように定義されています。

評価される可能性のある式として名前が表示される変数 は odr-used の要件を満たすオブジェクトでない限り、使用されない。 定数式に現れるための要件 (5.19) を満たすオブジェクトであり,lvalueからrvalueへの変換 (4.1) が直ちに適用される場合を除き, の変換(4.1)が直ちに適用される。

を[basic.def.odr]に追加しました。

編集:どうやらこれは間違った部分で、段落全体が異なるものに対する複数の定義を含んでいるようです。これはクラステンプレートのメンバ関数に関連するものである可能性があります。

オーバーロードされない関数で、その名前が評価される可能性のある式として現れるもの。 評価される可能性のある式として名前が表示されるオーバーロードされていない関数、または候補のセットのメンバー。 のメンバーである場合、オーバーロードの解決によって選択される。 評価される可能性のある式から参照されたときにオーバーロード解決によって選択された場合、純粋な仮想関数でない限り、odr-usedです。 仮想関数であり、その名前が明示的に修飾されていない限り、odr-used となります。

しかし、このルールが複数のコンパイル単位でどのように機能するのかが理解できません。クラステンプレートを明示的にインスタンス化した場合、すべてのメンバー関数がインスタンス化されるのでしょうか?

どのように解決するのですか?

これは単なる任意の定義で、標準では次のように使用されます。 エンティティの定義を提供する必要がある場合を指定します (単なる宣言とは対照的に)。 単なる宣言とは対照的に)。 この規格では、単に なぜなら、これは文脈によって多様に解釈されるからです。 というのも、これは文脈によって多様に解釈されるからです。 また、ODRの使用は、通常""used "と関連付けられるものには該当しないものもあります。 例えば、仮想関数は、その関数が使用されない限り、常にODR-usedです。 例えば、仮想関数は、それが純粋でない限り、たとえプログラムのどこにも呼び出されないとしても、常に ODR が使用されます。 たとえば、仮想関数は純粋でない限り、たとえプログラムのどこでも実際に呼び出されていなくても、常に ODR で使用されます。

完全な定義は §3.2 の第2段落にあります。 には、他のセクションへの参照が含まれ、定義が完成します。 を定義しています。

テンプレートに関して、ODR-usedは問題の一部でしかありません。 他の部分はインスタンス化です。 特に、§14.7では は、テンプレートがインスタンス化されるときを扱っています。 しかし、この2つは関連しています。 14.7.1(暗黙のインスタンス化)のテキストはかなり長いですが、基本的な原則は、テンプレートはただ単にインスタンス化されるだけです。 基本原則は、テンプレートが使用される場合にのみインスタンス化されることです。 この文脈では、usedはODR-usedを意味します。 したがって クラス・テンプレートのメンバ関数は、それが呼び出されたときだけインスタンス化されます。 呼び出された場合、または、それが仮想的でクラス自体がインスタンス化された場合にのみ インスタンス化されます。 この標準自体は、多くの場所でこのことを考慮しています。 という箇所でこのことに言及しています。 std::list<>::sort< を使いますが、個々の を使います。 をサポートしない < を呼び出さない限り、リストをインスタンス化することができます。 sort の上に を呼び出さない限りは