我有一段简单的代码(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的返回是为了能够做这些事情的确切目的,并且特殊的控制流将主导代码的外观。
答案 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;
}