如何在可变参数函数中模拟褶皱表达式

how to emulate fold expression in variadic function?

本文关键字:模拟 表达式 函数 参数 变参      更新时间:2023-10-16

似乎Microsoft支持折叠表达式的速度很慢,我正在努力寻找一种模拟它的方法。我有以下削减示例。这无法在Visual Studio 2017上编译,因为不支持Fold Expressions。知道如何模仿它吗?

template<typename... Args>
void get(weak_ptr<sqlite::database> awdb_, Args&&... args) {
    (*awdb_.lock() << ... << args);
}

在折叠表达式之前,有一个扩展器技巧:

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)...);
    }
}