c++ - 在类似功能的 reduce 函数中转发和返回类型

标签 c++ templates c++14 template-meta-programming temporary

我需要创建一个类似于 std::reducereduce 函数,但此函数不应处理容器,而应处理可变参数。

这是我目前拥有的:

template <typename F, typename T>
constexpr decltype(auto) reduce(F&&, T &&t) {
    return std::forward<T>(t);
}

template <typename F, typename T1, typename T2, typename... Args>
constexpr decltype(auto) reduce(F&& f, T1&& t1, T2&& t2, Args&&... args) {
    return reduce(
        std::forward<F>(f),
        std::forward<F>(f)(std::forward<T1>(t1), std::forward<T2>(t2)),
        std::forward<Args>(args)...);
}

以下按预期工作:

std::vector<int> vec;
decltype(auto) u = reduce([](auto &a, auto b) -> auto& {
        std::copy(std::begin(b), std::end(b), std::back_inserter(a));
        return a;
    }, vec, std::set<int>{1, 2}, std::list<int>{3, 4}, std::vector<int>{5, 6});

assert(&vec == &u); // ok
assert(vec == std::vector<int>{1, 2, 3, 4, 5, 6}); // ok

但以下不起作用:

auto u = reduce([](auto a, auto b) {
        std::copy(std::begin(b), std::end(b), std::back_inserter(a));
        return a;
    }, std::vector<int>{}, std::set<int>{1, 2}, 
    std::list<int>{3, 4}, std::vector<int>{5, 6});

这基本上是崩溃了——为了让它工作,我需要,例如将 reduce 的第一个定义更改为:

template <typename F, typename T>
constexpr auto reduce(F&&, T &&t) {
    return t;
}

但如果我这样做,第一个片段就不再起作用了。

问题出在reduce函数的参数转发和返回类型上,但是我能找到。

我应该如何修改我的 reduce 定义以使两个代码段都有效?

最佳答案

你可以试试

template <typename F, typename T>
constexpr T reduce(F&&, T &&t) {
    return std::forward<T>(t);
}

当第二个参数是右值时返回一个纯右值,否则返回一个引用参数的左值。你的片段似乎是 fine with it .

或者,只需使用您的第二个变体并将 vec 包装在 std::ref 中,mutatis mutandis。这也是模板按值处理对象时的标准方法。

关于c++ - 在类似功能的 reduce 函数中转发和返回类型,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45594500/

相关文章:

c++ - 转置模板参数包

c++ - 如何编写丢弃其参数的通用可变参数 lambda?

c++ - 在 opengl 中将多边形或立方体表示为集合粒子

c++ - 只读取二进制文件的第一行

c++ - 如何将焦点设置在特定的小部件上

Jquery tmpl 和谷歌搜索引擎优化

c++ - 使用 boost::iterator_facade<> 为迭代器返回 ref 但为 const_iterator 返回 const_ref?

c++ - AfxBeginThread 有很多开销吗?

c++ - 模板参数组合排序

c++ - Qt和std::string的通用高效修剪算法是什么?