如何解决成对的模板参数包剥离参数
我想为 ESP2866 微控制器创建一个函数,将任意数量的配置保存到文件系统上的配置文件中。我找到了一种方法,我想知道它是否会更好。
// Saves the configuration values to the file system
template <typename... Args>
void SaveConfig(const char *name,String &value,Args &...args)
{
Serial.println("Saving config...");
StaticJsonDocument<JSON_OBJECT_SIZE(2) + 200> doc;
SetData(doc,name,value,args...);
File configFile = SPIFFS.open("/config.json","w");
if (!configFile)
Serial.println("Failed to open config file for writing!");
serializeJson(doc,configFile);
serializeJson(doc,Serial);
configFile.close();
}
我需要做的就是:
doc[name] = value;
对于参数包中的每对参数。我的解决方案是我创建了一个新函数 SetData(),它使用参数包参数调用自身,每次迭代剥离两个参数:
template <typename... Args>
static void SetData(JsonDocument &doc,const char *name,Args &...args)
{
doc[name] = value;
SetData(doc,args...);
}
但这会产生另一个问题。当参数包“用完”时,它想调用没有参数的 SetData()。所以现在我必须创建一个没有参数的这个函数的重载(除了 doc)。
那么有没有更好的方法来做到这一点?
解决方法
如果你真的想使用模板而不是容器,你可以尝试以下方法:
template<typename ...Args,std::size_t ...I>
void SetDataImpl(JsonDocument& doc,std::tuple<Args...> tup,std::index_sequence<I...>) {
int dummy[] = {
(doc[std::get<2*I>(tup)] = std::get<2*I+1>(tup),0)...
};
}
template<typename ...Args>
void SetData(JsonDocument& doc,Args &...args) {
static_assert(sizeof...(args) % 2 == 0,"");
SetDataImpl(doc,std::forward_as_tuple(args...),std::make_index_sequence<sizeof...(args) / 2>{});
}
但正如@HolyBlackCat 提到的,这种方式会更好。
void SetData(JsonDocument& doc,std::initializer_list<std::pair<const char*,String>> il = {}) {
for(const auto& elem : il) { // Just auto& maybe. Depends on json library implementation
doc[elem.first] = elem.second;
}
}
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。