これはかなり混乱するかもしれませんが、私はBoostテストフレームワークを使ってユニットテストを書いています。私は、特定のコールバックが期待どおりに実行されたことをテストする変数をインクリメントするだけです。ラムダキャプチャされた変数のゴミ値がコールバック
これは、テストコードの抜粋である:
uint32_t nSuccessCallbacks = 0;
uint32_t nFailureCallbacks = 0;
auto successCallback = [&nSuccessCallbacks, this] {
std::cout << "Running success callback...\n";
++nSuccessCallbacks;
};
auto failureCallback = [&nFailureCallbacks, this] (const std::string& str) {
std::cout << "Error code: " << str << "\n";
std::cout << "Running failure callback...\n";
++nFailureCallbacks;
};
dest.advertise(rr, successCallback, failureCallback);
advertise
の定義:
void
NfdRibReadvertiseDestination::advertise(nfd::rib::ReadvertisedRoute& rr,
std::function<void()> successCb,
std::function<void(const std::string&)> failureCb)
{
m_controller.start<ndn::nfd::RibRegisterCommand>(
ControlParameters().setName(rr.getPrefix()).setOrigin(ndn::nfd::ROUTE_ORIGIN_CLIENT).setFlags(ndn::nfd::ROUTE_FLAG_CHILD_INHERIT),
[&] (const ControlParameters& cp) { successCb(); },
[&] (const ControlResponse& cr) { failureCb(cr.getText()); });
}
ちょうど参考のため、dest
がテストフィクスチャに定義されています。
nSuccessCallbacks
を変更できません。コールバックが呼び出されるたびに、正しく処理されますが、コールバックが終了してdest.advertise()
の後のコードに入っていれば、値は0です。コールバックラムダには正常に到達しますが、gdbはその変数が範囲。私はthis
のすべてのキャプチャ、特定のキャプチャ、ミキシングのすべての合理的な組み合わせを試してみました。キャプチャ句が間違って変数をキャプチャする理由はわかりません。私の最高の推測は、ラムダが別のラムダに渡されるので、最初のキャプチャ節は失われるということですか?
EDIT:インターフェイスオブジェクトがデータを受け取ったときにコールバックが実行されます。テストの後半で私たちはそれを模倣し、重要ではなかったので、私はそれを含めないことを選んだ。
私たちは水晶球に特定の問題を尋ねることになっていますか? – SergeyA
いいえ、キャプチャは "失われていません"。それらは参照によって捕捉される。これは、ラムダが実行されたときに、それらのカウンタがスコープ内にあることを意味します。彼らがすでに破壊されているならば、未定義の行動をしてください! –
ごみがどのように捕獲されているかを記述していません。上記のコードはラムダを決して実行しないので、そのようなイベントを説明することはできません。したがって、あなたは共有していない別の場所で問題が発生します。 – Yakk