将模板传递给异步函数

Pass a template to an async function

我正在尝试 运行 一个异步函数传递给它一个要执行的函数 f 和一个模板函数 f0 作为属性。

这是我通过模板创建的函数

DivideVerticesInThreads<0> f0(g, {}, {});

模板是

template <int NSegments, int Segment> struct SegmentVertices {
std::hash<Graph::vertex_descriptor> _h;
bool operator()(Graph::vertex_descriptor vd) const { return (_h(vd) % NSegments) == Segment; }
};

template <int N>
using DivideVerticesInThreads = boost::filtered_graph<Graph, boost::keep_all, SegmentVertices<4, N>>;

然后我这样调用async函数

auto handle = async(std::launch::async,f, f0);

然后我将函数 f:

传递给它
auto f = [&](G const& f0) {

    for(vp = vertices(f0); vp.first != vp.second; ++vp.first){
        //...
    }
};

完整的代码为:

template<typename G>
void parallel_count_adj_luby(G g){


    property_map<Graph,vertex_degree_t>::type deg = get(vertex_degree, g);


    auto f = [&](G const& g1) {

        for(vp = vertices(g1); vp.first != vp.second; ++vp.first){
            // ...
        }
    };

    DivideVerticesInThreads<0> f0(g, {}, {});

    auto handle = async(std::launch::async,f, f0);

}

问题是异步函数给我这个错误

error: no matching function for call to 'async(std::launch, parallel_count_adj_luby(G) [with G = boost::adjacency_list<boost::vecS, boost::vecS, boost::undirectedS, boost::property<boost::vertex_color_t, int, boost::property<boost::vertex_degree_t, int> > >]::<lambda(const boost::adjacency_list<boost::vecS, boost::vecS, boost::undirectedS, boost::property<boost::vertex_color_t, int, boost::property<boost::vertex_degree_t, int> > >&)>&, DivideVerticesInThreads<0>&)'
         auto handle = async(std::launch::async,f, f0);

我不太了解c++和未来,所以错误可能是一些虚拟的。我做错了什么?

我有点同意评论者的观点,

但是,我想我知道发生了什么是由于我在 时做出的选择。

看来我专注于效率,它让您遇到了您不知道如何处理的 C++ 挑战。

我只是要忽略混淆并删除带有运行时参数的静态类型参数。这样你过滤的图段都可以有相同的静态类型

Live On Compiler Explorer

#include <boost/graph/adjacency_list.hpp>
#include <boost/graph/filtered_graph.hpp>
#include <boost/graph/random.hpp>
#include <iostream>
#include <random>

static std::mt19937 s_prng(std::random_device{}());

using G = boost::adjacency_list<>;
using V = G::vertex_descriptor;

struct SegmentVertices {
    unsigned nsegments, segment;

    bool operator()(V vd) const {
        return (std::hash<V>{}(vd) % nsegments) == segment;
    }
};

using F = boost::filtered_graph<G, boost::keep_all, SegmentVertices>;

G make_graph() {
    G g;
    generate_random_graph(g, 32 * 1024 - (s_prng() % 37), 64 * 1024, s_prng);
    return g;
}

void the_function(G const& g)
{
    std::cout << "Full graph " << size(boost::make_iterator_range(vertices(g)))
              << " vertices\n";
}

void the_function(F const& f)
{
    auto& pred = f.m_vertex_pred;

    std::cout << pred.segment << "/" << pred.nsegments << " "
              << size(boost::make_iterator_range(vertices(f))) << " vertices\n";
}

int main()
{
    G g = make_graph();
    the_function(g);

    unsigned NSegments = s_prng() % 10 + 2;

    for (unsigned seg = 0; seg < NSegments; ++seg) {
        the_function(F(g, {}, {seg, NSegments}));
    }
}

打印例如

Full graph 32736 vertices
0/3 10912 vertices
1/3 10912 vertices
2/3 10912 vertices

Full graph 32741 vertices
0/7 4678 vertices
1/7 4678 vertices
2/7 4677 vertices
3/7 4677 vertices
4/7 4677 vertices
5/7 4677 vertices
6/7 4677 vertices

如您所见,使用运行时过滤器参数以性能换取运行时灵活性和类型便利性。


¹ 例如即使是第一个声明“这是我通过模板创建的函数”也是没有意义的,因为接下来的不是函数,也没有模板被用来创建它。