我有大量的if语句,我想把它变成一个循环:
if (intParams.find(paramName) != intParams.end()) {
return (float)intParams.at(paramName);
} else if (floatParams.find(paramName) != floatParams.end()) {
return (float)floatParams.at(paramName);
} else if (boolParams.find(paramName) != boolParams.end()) {
return (float)boolParams.at(paramName);
}
return defaultVal;我想把它变成一个循环或者折叠表达式来简化逻辑,但是这很困难,因为intParams有Map<string, int64_t>类型,floatParams有类型Map<string, float>,boolParams有类型Map<string, bool>。我试过翻看boost,但找不到合适的东西。
我想把这个简化成
for (auto& param : {intParams, floatParams, boolParams}) {
if (param.find(paramName) != param.end()) {
return (float)param.at(paramName);
}
}
return defaultVal;让我知道我能做什么!
发布于 2020-06-14 03:58:39
float retval=defaultVal;
auto all_maps = [&](auto&...maps){
auto one_map = [&](auto&map){
auto it = map.find(paramName);
if (it==map.end()) return false;
retval=static_cast<float>(it->second);
return true;
};
return ( one_map(maps) || ... );
};
all_maps(intParams, floatParams, boolParams);
return retval;如果要避免对默认情况进行分配,则可以使用可选选项。
此外,还有可能工作的递归解决方案。
发布于 2020-06-14 03:46:44
您可以使用折叠表达式和帮助类模板执行令人惊讶的操作:
template<class T>
struct Search {
Search(const Map<std::string,T> &m,const std::string &k)
: m(m),k(k) {} // for CTAD (until C++20)
friend std::optional<float> operator|(const std::optional<float> &f,const Search<U> &s) {
if(!f)
if(const auto i=s.m.find(s.k); i!=s.m.end())
return static_cast<float>(*i);
return f;
}
private:
const Map<std::string,T> &m;
const std::string &k;
};
template<class ...TT>
float get(const Map<std::string,TT> &...mm,const std::string &k,float defaultVal) {
return (std::nullopt | ... | Search(mm,k)).value_or(defaultVal);
}https://stackoverflow.com/questions/62367513
复制相似问题