我总是尽可能使用STL风格的算法,因为它们简洁并且表达力很强。
我有一个库中的这段代码:
理想情况下,我希望写出真正的代码片段如下:
显然,像
你有什么建议?应该保留代码吗?还是有类似于算法的方法可以重新编写它?
编辑:
如评论中所述,
我有一个库中的这段代码:
auto& findFlag(const std::string& mName)
{
for(auto& f : makeRangeCastRef<Flag>(getFlags()))
if(f.hasName(mName))
return f;
throw Exception::createFlagNotFound(mName, getNamesStr());
}
我希望用现代的C ++算法形式来编写它,但我无法解决早期的return
和可能的throw
问题。
for(auto& value : container) if(predicate(value)) return value;
// ^~~~~~
// IMPORTANT: return from the caller function, not the algorithm itself
理想情况下,我希望写出真正的代码片段如下:
auto& findFlag(const std::string& mName)
{
early_return_if(makeRangeCastRef<Flag>(getFlags()),
[&mName](const auto& f){ return f.hasName(mName); });
throw Exception::createFlagNotFound(mName, getNamesStr());
}
显然,像
early_return_if
这样的东西是不存在的——据我所知,无法从被调用函数中调用return
到调用者函数。虽然return early_return_if(...)
可能可行,但这样就无法抛出异常,除非创建一个特定的算法来抛出异常。你有什么建议?应该保留代码吗?还是有类似于算法的方法可以重新编写它?
编辑:
如评论中所述,
std::find_if
是一个不错的选择,但是有一个不必要的检查可以避免:auto& findFlag(const std::string& mName)
{
auto container(makeRangeCastRef<Flag>(getFlags())); // Need to write this out...
// Need to keep track of the returned iterator...
auto it(findIf(container, [&mName](const auto& f){ return f.hasName(mName); }));
if(it != container.end()) return *it; // I don't like this either...
throw Exception::createFlagNotFound(mName, getNamesStr());
}
auto it = std::find_if(begin(container), end(container), predicate); return it != end(container) ? *it : throw /*...*/;
- T.C.std :: find_if
,但it != end(container)
的检查是不必要的,我想避免这种情况。 - Vittorio RomeoO(N)
次比较。你在意的是,在所有比较都失败的情况下,你会多做一次比较吗? - luk32