7

次の例があるとします。

#include <cstdlib>

class A {
public:
    static const std::size_t value = 42;
};

要するに、値(コンパイル時に決定される)で呼び出されるメンバーAを持つクラスを持っています(または、より良い、欲しい)。static const std::size_tvalue42

さて、IIRC、これは特定の状況下でのみうまく機能します。たとえば、のアドレスを取得する場合はそうではありませんA::valueこれがすべてのケースで正常に機能するためには、実装ファイルに定義を追加する必要があります。

const std::size_t A::value;

ただし、このファイルをヘッダーのみにしたいので、これはできません。別の一般的な解決策は次のとおりです。

class A {
public:
    enum { value = 42 };
};

の型を にしたいので、この解決策も好きではありませA::valuestd::size_t

この問題の良い解決策は何ですか? できれば、小さくてポータブルなソリューションであり、 のような巨大なマクロ マジックを備えたものではありませんBOOST_STATIC_CONSTANT


C++11 ではなく、C++03 のソリューションが欲しいです (それは些細なことです)。

4

1 に答える 1

8

まず、size_t数値に符号なし型を使用すると、暗黙のプロモーションの問題が発生する可能性があります。したがって、に対応する符号付きタイプを使用することをお勧めします。これはと呼ばれptrdiff_tます。これは、たまたま、ポインター差分式の結果タイプです。

また、C ++ 11での変更により、一般に、を含めるのではなく、含めることをお<stddef.h>勧め<cstddef>::ptrdiff_t ます。ptrdiff_tstd::ptrdiff_t

さて、これがヘッダーファイルの外部リンケージ定数を行う方法です:

template< class Dummy >
struct A_constants_
{
    static ::ptrdiff_t const value;
};

template< class Dummy >
::ptrdiff_t const A_constants_<Dummy>::value = 42;

typedef A_constants_<void> A_constants;

class A
    : public A_constants
{
public:
    // Whatever
};

次に、次のように使用できます。

foo( A::value );

これを行う方法は他にもいくつかありますが、上記は最も簡単で簡単に正しく実行できる方法です。

于 2012-09-07T22:15:04.530 に答える