在执行std :: for_each期间累积结果,该结果被异常中断

时间:2013-12-06 15:15:17

标签: c++ std

我有一段简单的代码(Checker),它对向量的元素(pps)执行一些一致性检查

try{
    const Checker& results = std::for_each(pps.begin(), pps.end(), Checker());
    !results.diagnostic();
}
catch(std::bad_alloc&){
    cout << "the check operation failed: out of memory" << endl;
}

Checker有一个成员函数(diagnostic),用于输出此项检查的结果。

问题是:如果由于某种原因(例如std::bad_alloc)检查操作被中断,我希望已经生成的诊断可用。是否有可能不再经历“重大改写”,允许我做类似的事情:

Checker::Diagnostic diagnostic;
try{
    std::for_each(pps.begin(), pps.end(), Checker(diagnostic));
}
catch(std::bad_alloc&){
    cout << "the check operation failed: out of memory" << endl;
}
diagnostic.output();

这看起来不自然,因为std :: for_each的返回是为了能够做这些事情的确切目的,并且特殊的控制流将主导代码的外观。

1 个答案:

答案 0 :(得分:1)

我更喜欢使用这样的类:

Checker checker;
checker.doCheck(pps);
checker.diagnostic();

或者:

const Checker checker(pps);
checker.diagnostic();

这样,您可以在doCheck()(第一个示例)或构造函数(第二个示例)中隐藏检查的详细信息。

例如:

#include <algorithm>
#include <iostream>
#include <vector>

#include <boost/bind.hpp>

using ImportantItems = std::vector<int>;

class Checker {

public:

    Checker(const int criticalItem) : criticalItem(criticalItem) { }

    void doCheck(const ImportantItems& items)
    {
        accumulatedSum = 0;
        try {
            std::for_each(
                    items.begin(), items.end(), 
                    boost::bind(&Checker::performExtensiveCheckingOnAnItem, this, _1));
            this->dataOk = true;
        }
        catch (const std::runtime_error& e) {
            this->dataOk = false;
        }
        std::cout << "AddAccumulated sum: " << accumulatedSum << std::endl;
    }

    void diagnostic() const
    {
        if (this->dataOk) {
            std::cout << "Everything was fine in last check" << std::endl;
        }
        else {
            std::cout << "Serious problems encountered" << std::endl;
        }
    }

private:

    void performExtensiveCheckingOnAnItem(const int anItem)
    {
        if (criticalItem == anItem) {
            throw std::runtime_error("Critical situation");
        }
        accumulatedSum += anItem;
    }

    const int criticalItem;
    int accumulatedSum{};
    bool dataOk{false};

};

int main()
{
    const int criticalItem(5);

    const ImportantItems importantItems{1, 2, 3, 4/*, criticalItem*/};

    Checker checker(criticalItem);
    checker.doCheck(importantItems);
    checker.diagnostic();

    return 0;
}