我正在尝试新的 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 替换为具体化容器:
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 fromnode
, then this is not a real issue and you can disregard this comment.PHYSIC MODE ENGAGED:
If your issue was that
g
isGraph const&
and the view is not readonly, either
- make
mView
anany_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 thevertex_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
ortypename boost::graph_traits<Graph>::vertex_descriptor
- making the operator() non-template
关于c++ - 作为数据成员的范围 View ,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56078331/