我试图编写一个模板函数,它应该将对象(不同类型的对)写入文件。就像这样:
for (auto iter = container.begin(); iter != container.end(); ++iter) {
for (auto iter2 = std::vector<type>::reverse_iterator(iter); iter2 != container.rend(); ++iter2) {
// do stuff
}
}
问题是,我刚刚意识到,我需要在调用此函数时传递template<class A, class B>
void write_parameters(const std::string &file_name, std::initializer_list<std::pair<A, B>> parameters) {
std::ofstream file;
if (!file_exists(file_name)) {
file.open(file_name, std::ios_base::app);
} else {
file.open(file_name);
}
if (!file) {
throw std::runtime_error("file failed to be created");
}
for (std::pair<A, B> p : parameters) {
file << std::string(p.first) << " = " << std::string(p.second) << "\n";
}
file << "---------------------------------------------\n";
file.close();
}
和A
的类型,因此我无法使用多个不同的地图调用此函数,或者可以我?
以下是我试图打电话的内容:
B
但这不起作用,因为例如write_parameters<std::string, std::string>(std::string("parameters/") + s.instance_name, {
{"starting_node", std::string(starting_node},
{"max_iter", max_iter},
{"nice_gain", nice_gain},
{"lazy", lazy},
{"random_start", random_start}
});
不是字符串。如何解决此问题而无需为每张地图调用max_iter
?
答案 0 :(得分:1)
传递并捕获一对对应于您想要写入的参数的对。然后你使用这个很酷的技巧来调用包中每个参数的可调用:
namespace detail{
template<class F,class...Ps>
void invoke( F&& f, Ps&&... ps ) {
using pack=int[];
(void)pack{((f(move(ps)),0))...};
}
}
现在变为:
template<class...Ps>
void write_parameters( std::string const& file_name, Ps&&... ps) {
std::ofstream file(file_name,ios_base::app|ios_base::out);
if (!file) {
throw std::runtime_error("file failed to be created");
}
detail::invoke(
[&](auto&& p) { file << p.first << " " << p.second << '\n'; },
forward<Ps>(ps)...
);
}
int main() {
write_parameters(
"parameters/" + s.instance_name,
make_pair("starting_node", starting_node),
make_pair("max_iter", max_iter),
make_pair("nice_gain", nice_gai),
make_pair("lazy", lazy),
make_pair("random_start", random_start)
);
}