web-dev-qa-db-ja.com

何かを「ODRで使用する」とはどういう意味ですか?

これは、 別の質問 のコンテキストで発生しました。

クラステンプレートのメンバー関数は、ODRが使用されている場合にのみインスタンス化されるようです。誰かが正確にそれが何を意味するのか説明してもらえますか。 One Definition Rule(ODR)に関するウィキペディアの記事 には、「ODR-use」は記載されていません。

ただし、標準では次のように定義されています

名前が潜在的に評価される式として表示される変数は、定数式(5.19)に表示するための要件を満たすオブジェクトでない限り、odr-usedです)および左辺値から右辺値への変換(4.1)がすぐに適用されます。

[basic.def.odr]で。

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

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

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

77
Sarien

プレーンワードでは、odr-usedは、その定義が存在する必要があるコンテキストで何か(変数または関数)が使用されることを意味します。

例えば。、

struct F {
   static const int g_x = 2;
};

int g_x_plus_1 = F::g_x + 1; // in this context, only the value of g_x is needed.
                             // so it's OK without the definition of g_x

vector<int>  vi;
vi.Push_back( F::g_x );      // Error, this is odr-used, Push_back(const int & t) expect
                             // a const lvalue, so it's definition must be present

上記のPush_backはMSVC 2013で渡されます。この動作は標準に準拠していないため、gcc 4.8.2とclang 3.8.0の両方が失敗しました。エラーメッセージは次のとおりです。undefined reference to `K :: g_x '

15
zhaorufei