2016-12-14 9 views
2

投稿者another question私は、クラス定義やインライン関数でODR違反が発生するため、匿名名前空間のヘッダーファイルからオブジェクトや関数を使用できないことに気付きました。この場合、constまたはconstexprstaticというオブジェクトをinlineの関数またはクラスに安全に使用することは可能ですか?たとえば、CONSTANTnamespaceの中にある場合、それは安全ではありませんが、静的なリンケージで定数を使用するのは問題ありませんか?ODR準拠ヘッダーファイルの定数を使用

// some header file to be included by multiple .cpp files 
static const/*expr*/ int CONSTANT = 2; 

inline int f() { 
    return CONSTANT; 
} 

class Cls { 
    int mem = CONSTANT; 
}; 
+1

少なくともC++ではこれはもはや問題ではありません。奇妙なことに、タイプエイリアスはあなたの問題を解決することができます: 'CONSTANT = std :: integral_constantを使用すると; – Barry

+0

@Mオブジェクトのオブジェクトはodr-usedではありません。 –

+0

N4606(これはisocpp.orgによる最新の標準ドラフト)はまだ "オブジェクトはodr-usedではありません" –

答えて

4

このコードはOKです。完全な段落(C++ 14 [basic.def.odr/6.2])である:Dの各定義において

、名前を対応する、3.4によれば見上げ、定義内で定義されたエンティティを指すものDの同一の実体を参照するか、過負荷解決の後で、部分テンプレート特殊化のマッチングの後で同じオブジェクトを参照するものとする。ただし、オブジェクトが同じリテラル型を持つ場合、名前は不揮発性の すべての定義はDであり、オブジェクトは定数式で初期化され、オブジェクトはodr-usedではなく、オブジェクトはすべての定義で同じ値を持つDです。

  • CONSTANT実際に非を参照んと

この使用法は、「...を除くと...と...」の部分でのすべての条件が一致しませんvolatile const内部リンケージを持つオブジェクト

  • すべての定義において同じf()のリテラルタイプを持ちます。
  • 定数式2で初期化されます。
  • odr-usedではありません。
  • f()のすべての定義において同じ値を持ちます。
  • ポイント「それは使用ODR-ではありませんが、」「それは使用ODR-f()ではない」ことを意味することになっている - あなたはodr-に起こるならば、それはf()を破壊しない、すなわち、プログラムの別の場所でCONSTANTを使用してください。

    +1

    これは間違いなく「Dの定義内でodrが使用されていない」という意味です。 –

    +0

    @ T.C。 https://github.com/cplusplus/draft/pull/1243 –

    +0

    完了です。標準が変更されました! –