微软似乎对Fold Expressions的支持很慢,而我正在努力寻找一种模拟它的方法。我有以下示例。由于不支持折叠表达式,因此无法在Visual Studio 2017上编译。
知道如何模仿吗?
template<typename... Args>
void get(weak_ptr<sqlite::database> awdb_, Args&&... args) {
(*awdb_.lock() << ... << args);
}
最佳答案
在折叠表达式之前,有expander trick:
template <class... Args>
void get(weak_ptr<sqlite::database> awdb_, Args&&... args) {
if (auto db = awdb_.lock()) {
using expander = int[];
(void)expander{0,
(void(*db << std::forward<Args>(args)), 0)...
};
}
}
作为T.C.指出,如果
<<
除了返回*this
以外还执行其他操作,则这不一定严格等效,因此我们可以这样写:template <class F, class Arg>
decltype(auto) fold(F&& , Arg&& arg) {
return std::forward<Arg>(arg);
}
template <class F, class A0, class A1, class... Args>
decltype(auto) fold(F&& f, A0&& a0, A1&& a1, Args&&... args) {
return fold(f, f(a0, a1), std::forward<Args>(args)...);
}
template <class... Args>
void get(weak_ptr<sqlite::database> awdb_, Args&&... args) {
if (auto db = awdb_.lock()) {
auto lshift = [](auto&& a, auto&& b) -> decltype(auto) { return a << std::forward<decltype(b)>(b); };
fold(lshift, *db, std::forward<Args>(args)...);
}
}