これは、私が使用しなければならない一般的なコードパターンです。
class foo {
public:
void InitMap();
void InvokeMethodsInMap();
static void abcMethod();
static void defMethod();
private:
typedef std::map<const char*, pMethod> TMyMap;
TMyMap m_MyMap;
}
void
foo::InitMap()
{
m_MyMap["abc"] = &foo::abcMethod;
m_MyMap["def"] = &foo::defMethod;
}
void
foo::InvokeMethodsInMap()
{
for (TMyMap::const_iterator it = m_MyMap.begin();
it != m_MyMap.end(); it++)
{
(*it->second)(it->first);
}
}
ただし、(for ループ内で) マップが処理される順序は、ビルド構成がリリースかデバッグかによって異なる場合があることがわかりました。リリース ビルドで発生するコンパイラの最適化がこの順序に影響しているようです。
begin()
上記のループで使用し、各メソッド呼び出しの後に反復子をインクリメントすることで、初期化順にマップを処理すると考えました。ただし、マップはハッシュ テーブルとして実装され、順序が保証されないことも読んだことを覚えています。
ほとんどの単体テストはデバッグ ビルドで実行され、多くの場合、外部の QA チームがテストを開始するまで (リリース ビルドを使用しているため)、奇妙な順序依存関係のバグが検出されないため、これは特に厄介です。
誰かがこの奇妙な振る舞いを説明できますか?