制作比较器功能的矢量

时间:2016-08-21 11:15:07

标签: c++ vector c++14 std-function

我的问题是测试具有不同比较器功能的快速排序的实现:std::lessstd::greater。但我不想复制粘贴两个比较器中不同的测试代码,所以我想将它们放入一个矢量(或者其他东西?)并迭代它们。

为了简化这篇文章,我想说我想在两个函数的向量上写一个循环,它将01作为参数并输出一个布尔值。以下是我的看法:

#include <iostream>
#include <vector>
#include <functional>

int main() {
    auto fs = std::vector<>{std::less<int>{}, std::greater<int>{}};

    for (auto f: fs) {
        std::cout << f(0, 1) << " ";
    } std::cout << std::endl;
}

我的g++ 6.1.1编译器正确地抱怨我没有为向量指定模板参数。我一直在尝试std::function<bool(int, int)>和其他没有运气的事情。

你能告诉我如何解决这段代码吗?

更新:我得到的确切错误:

% g++ -std=c++14 -Wall deleteme.cpp && ./a.out
deleteme.cpp: In function ‘int main()’:
deleteme.cpp:6:27: error: wrong number of template arguments (0, should be at least 1)
     auto fs = std::vector<>{std::less<int>{}, std::greater<int>{}};
                           ^
In file included from /usr/include/c++/6.1.1/vector:64:0,
                 from deleteme.cpp:2:
/usr/include/c++/6.1.1/bits/stl_vector.h:214:11: note: provided for ‘template<class _Tp, class _Alloc> class std::vector’
     class vector : protected _Vector_base<_Tp, _Alloc>
           ^~~~~~
deleteme.cpp:8:18: error: unable to deduce ‘auto&&’ from ‘fs’
     for (auto f: fs) {
                  ^~

2 个答案:

答案 0 :(得分:2)

仅从C ++ 17开始,构造函数的模板参数可用于推导出类型的模板参数,因此您必须编写std::vector<std::function<bool(int,int)>>而不是std::vector<>

请注意,与直接调用函数相比,std::function会产生性能开销,因此您可能需要查看可变参数模板参数(和swallowing)以获取最后几个百分比

答案 1 :(得分:0)

当你使用不同的类型时,你可能会使用元组,并迭代元组:

namespace detail {
    template <typename F, typename TUPLE, std::size_t ... Is>
    void run_for_each(F&& f, TUPLE&& t, std::index_sequence<Is...>)
    {
        const int dummy[] = {0, (f(std::get<Is>(std::forward<TUPLE>(t))), void(), 0)...};
        static_cast<void>(dummy); // Avoid warning for unused variable
    }
}

template <typename F, typename TUPLE>
void run_for_each(F&& f, TUPLE&& t)
{
     detail::run_for_each(std::forward<F>(f),
                          std::forward<TUPLE>(t),
                          std::make_index_sequence<
                              std::tuple_size<std::decay_t<TUPLE>>::value>());
}

然后

int main() {
    auto t = std::make_tuple(std::less<int>{}, std::greater<int>{});

    run_for_each([](auto&&f) {std::cout << f(0, 1) << " ";}, t);
    std::cout << std::endl;
}

Demo