24

このサンプルコードを考えてみましょう。

template<class D>
char register_(){
    return D::get_dummy(); // static function
}

template<class D>
struct Foo{
    static char const dummy;
};

template<class D>
char const Foo<D>::dummy = register_<D>();

struct Bar
    : Foo<Bar>
{
    static char const get_dummy() { return 42; }
};

イデオネにも。)

dummyの具体的なインスタンス化が行われるとすぐに初期化されることを期待しFooていBarます。この質問(および最後の標準引用)は、なぜそれが起こらないのかをかなり明確に説明しました。

[...]特に、静的データメンバーの定義が存在する必要がある方法で静的データメンバー自体が使用されない限り、静的データメンバーの初期化(および関連する副作用)は発生しません。

または(インスタンスがないため、コンストラクターのトリックがない)を使用せずに、またユーザーが何らかの方法でメンバーを明示的に指定する必要なしに、強制 dummy的に初期化(効果的に呼び出すregister_)する方法はありますか?派生クラスが何もする必要がないための追加のCookie。BarFooFoo


編集:派生クラスへの影響を最小限に抑える方法を見つけました:

struct Bar
    : Foo<Bar>
{   //                              vvvvvvvvvvvv
    static char const get_dummy() { (void)dummy; return 42; }
};

ただし、派生クラスにはそれを行わなくてもよいのですが。:|

4

6 に答える 6

12

検討:

template<typename T, T> struct value { };

template<typename T>
struct HasStatics {
  static int a; // we force this to be initialized
  typedef value<int&, a> value_user;
};

template<typename T>
int HasStatics<T>::a = /* whatever side-effect you want */ 0;

メンバーを紹介しなくても可能です。

template<typename T, T> struct var { enum { value }; };
typedef char user;

template<typename T>
struct HasStatics {
  static int a; // we force this to be initialized
  static int b; // and this

  // hope you like the syntax!
  user :var<int&, a>::value,
       :var<int&, b>::value;
};

template<typename T>
int HasStatics<T>::a = /* whatever side-effect you want */ 0;

template<typename T>
int HasStatics<T>::b = /* whatever side-effect you want */ 0;
于 2011-06-23T14:12:16.960 に答える
0

そのようなことが頭に浮かびます:

// in some c++ file (to make i with internal linkage)
static int i = init_dummy(Foo<int>::dummy);

ここで、init_dummy は次のように定義されます。

int init_dummy(...)
{
  return 1;
}

可変引数により、次のように初期化を追加できます。

static int i = init_dummy(Foo<int>::dummy, Foo<double>::dummy, Foo<whatever>::dummy);
于 2011-06-23T14:08:02.193 に答える
-1

Bar で設定した値をどのように確認していますか。私はあなたのコードを変更し、次のように bar に別の関数を追加しました:

....
static char const get_dummy(int){return Foo<Bar>::dummy;}
....

そして、それはまさに期待される結果を私に与えています。私は正しく理解していないかもしれませんが、あなたは正確に何を達成したいですか?

静的メンバーはオブジェクト間で共有されるため、アクセス時にスコープを解決する必要があります。これが、これがアクセスしたいクラスのメンバーであることをコンパイラーに明示的に伝えることによって :: を使用する理由です。

于 2011-06-22T20:39:35.300 に答える
-2

Bar または Foo のインスタンスなしでダミーを強制的に初期化する (事実上 register_ を呼び出す) 方法はありますか (インスタンスがないため、コンストラクターのトリックはありません)。

これで十分ではないでしょうか。

std::cout << Foo<int>::dummy;
于 2011-06-21T06:08:40.853 に答える