次のコードを検討してください。
#include <iostream>
struct X {
int foo() {
// Can I get this to be an instance-specific static variable, please?
static int i = 0;
return i++;
}
};
int main() {
X a, b;
std::cout << a.foo() << ' ';
std::cout << b.foo() << ' ';
std::cout << b.foo() << '\n';
// output is: 0 1 2
// desired output: 0 0 1
}
宣言と初期化を遠く離れたヘッダーとコンストラクターに移動する必要なく、i
インスタンスごとにこの静的変数のコピーを取得することは可能ですか?X
これが必要な理由は、この変数の値がこの特定の関数内でのみ関連するためです (しかし、それがメンバー関数であるインスタンスにも固有です)。たとえば、最後の呼び出しパラメーター、最後の呼び出しの時刻などです。
このアイデアの背後にあるクラスは、すでにある程度大きくなっており、1 つの関数内で使用されるそのような小さな変数の宣言と初期化が見苦しくなっています。
更新:メモリをリークしたくないことに注意してください。インスタンスが破棄されると、それに関連付けられている変数も削除する必要があります。
Update²:明らかに (そして残念ながら) この正確なセマンティクスを持つ適切な言語機能は実際にはありません。いくつかの回避策がありますが、それぞれに制限と落とし穴があります。
- 「関数」宣言と定義の配置
- 他の「実際の」メンバー変数へのアクセス
- 派生クラスで「関数」をオーバーロードする
- ...
これらの意味を念頭に置いて、頭に浮かぶ最初のことを固守するのが最も効率的であるように思われます。
struct A {
int j = 0;
int i = 0;
int foo() { return i++ + j++; }
};
このようなものに行くのではなく:
struct B {
int j = 0;
std::function<int()> foo =
[this, i = 0]() mutable { return i++ + this->j++; };
};
またはこれ:
struct C {
int j;
struct Foo {
int i;
C *c;
Foo(C *c) : i(), c(c) {}
int operator() () { return i++ + c->j++; }
} foo;
C() : j(), foo(this) {}
};
またはこれ:
struct D {
int j = 0;
std::map<std::string, int> i;
int foo() { return i[__PRETTY_FUNCTION__]++ + j++; }
};
または類似。
コメントと回答をありがとうございます!