c++ - 作为数据成员的范围 View

标签 c++ boost-graph range-v3

我正在尝试新的 range-v3 库(0.5.0、clang-7.1)

我正在遍历一个图(bfs)。图中的每个节点都包含一些 vector 数据 ( std::vector<double> )。在遍历图表时,我尝试创建一个 concat_view (这是所有 vector 的串联)。

我正在尝试存储此concat_view作为图遍历类的成员变量。 (准确地说,default_bfs_visitor 来自 boost 图形库)。所以,预先,我不知道我将遇到多少个 vector 。我正在做这样的事情。

struct bfs_visitor 
{
private:
    ranges::v3::any_view<double> mView;
public:
    template<class Graph>
    void finish_vertex (vertex_descriptor v, const Graph& g) 
    {
        auto node = g[v];
        std::vector<double>& data = dataForNode(node);
        mView = ranges::v3::concat(mView, data);
    }
};

访问完图表后,我会处理 View 以提取所需的信息。

作为 mView 的类型每个 concat 都会发生变化操作时,我无法显式指定 mView 的类型在声明中。

This link表示 any_view 的性能受到影响。是any_view唯一的选择?

最佳答案

你把问题解决了:

  • ranges::v3::concat的返回类型是不同的,所以你需要类型删除(例如any_view)。
  • 类型删除惰性组合范围在性能方面是一个坏主意

在您的情况下,我会毫不犹豫地将 View 替换为具体化容器:

Live On Coliru

struct bfs_visitor 
{
private:
    std::vector<std::reference_wrapper<double> > mView;
public:
    template<class Graph>
    void finish_vertex (vertex_descriptor v, const Graph& g) 
    {
        auto& node = g[v];
        ranges::v3::push_back(mView, dataForNode(node));
    }
};

NOTE IMPORTANT

Note that I made auto& node a reference, instead of taking a copy. Concatenating views of temporary copies is a bad idea (UB).

If you happen to know that dataForNode(node) does NOT return a reference to member data from node, then this is not a real issue and you can disregard this comment.

PHYSIC MODE ENGAGED:

If your issue was that g is Graph const& and the view is not readonly, either

  • make mView an any_view<double const>
  • store a non-const pointer to your graph in the visitor and use that instead of the g argument

事实上,如果您根本不需要它们作为引用(这是 View 的关键属性):

struct bfs_visitor 
{
private:
    std::vector<double> mCollectedData;
public:
    template<class Graph>
    void finish_vertex (vertex_descriptor v, const Graph& g) {
        ranges::v3::push_back(mCollectedData, dataForNode(g[v]));
    }
};

Note Another slightly weird thing is that your visitor templates the Graph argument type, but not the vertex_descriptor. Again, it's hard to know whether it's actually wrong without seeing the rest of the code, but it's certainly a-typical.

The vertex descriptor type is characteristic of the Graph type, so consider - writing typename Graph::vertex_descriptor or typename boost::graph_traits<Graph>::vertex_descriptor - making the operator() non-template

关于c++ - 作为数据成员的范围 View ,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56078331/

相关文章:

c++ - boost::counting_iterator range-v3 中的模拟

c++ - 如何可视化这些没有出现的数字。 (C++)

c++ - 使用 write_graphviz() 打印一个 constified 子图

c++ - vector 的最后一项不显示/vector 索引问题

c++ - 如何从过滤后的数据创建笛卡尔积范围?

c++ - 使用 Ranges-v3 view::join 保留双向性

c++ - 在 Mingw32 中编译 SystemC 库

c++ - 从四个 __m128i 变量的 64 高位或低位初始化 __m256i

c++ - qwt中的魔法数字

c++ - 具有自定义顶点和边的 Boost Graph