我有一大组 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>
。我试过查看提升,但找不到合适的东西。
我想将其简化为类似
for (auto& param : {intParams, floatParams, boolParams}) {
if (param.find(paramName) != param.end()) {
return (float)param.at(paramName);
}
}
return defaultVal;
让我知道我能做什么!
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;
如果要避免分配默认值,可以使用可选。
还有一些 if constexpr 递归解决方案可以工作。
您可以使用折叠表达式和帮助程序类模板执行惊人的操作:
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);
}