представление диапазона как элемент данных - PullRequest
2 голосов
/ 10 мая 2019

Я пробую новую библиотеку range-v3 (0.5.0, clang-7.1)

Я пересекаю график (bfs).Каждый узел на графике содержит некоторые векторные данные (std::vector<double>).Проходя по графику, я пытаюсь создать concat_view (который является объединением всех векторов).

Я пытаюсь сохранить это concat_view как переменную-член класса обхода графа.(default_bfs_visitor из библиотеки графов буста, если быть точным).Итак, заранее, я не буду знать, сколько векторов я собираюсь встретить.Я делаю что-то вроде этого.

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);
    }
};

После того, как я закончу посещение графика, я обрабатываю представление для извлечения необходимой информации.

Поскольку тип mView меняется с каждой операцией concat, я не могу явно указать тип mView в объявлении.

Эта ссылка говорит о снижении производительности на any_view.any_view единственный вариант?

1 Ответ

4 голосов
/ 10 мая 2019

Вы прибиваете проблему на голову:

  • тип возвращаемого значения ranges::v3::concat отличается, поэтому вам нужно стереть тип (any_view, например.).
  • стертые ленивые составные диапазоны - плохая идея с точки зрения производительности

В вашей ситуации я без колебаний заменил бы представление контейнером reified :

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));
    }
};

ПРИМЕЧАНИЕ ВАЖНО

Обратите внимание, что я сделал ссылку auto& node вместо того, чтобы взять копию. Объединение представлений временных копий - это плохая идея (UB) .

Если вам известно, что dataForNode(node) НЕ возвращает ссылку на данные участника из node, то это не настоящая проблема, и вы можете игнорировать этот комментарий.

Включен физический режим:

Если ваша проблема заключалась в том, что g равен Graph const&, и представление не только для чтения, либо

  • Марка mView и any_view<double const>
  • сохраните неконстантный указатель на ваш график в посетителе и используйте его вместо g аргумента

На самом деле, если вам вообще не нужны ссылки в качестве ссылок (это ключевое свойство представления):

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]));
    }
};

Примечание Еще одна немного странная вещь заключается в том, что ваш посетитель шаблонирует тип аргумента Graph, но не vertex_descriptor. Опять же, трудно понять, действительно ли это неправильно, не видя остальной код, но это, конечно, типично.

Тип дескриптора вершины является характеристикой типа Graph, поэтому рассмотрим - написание typename Graph::vertex_descriptor или typename boost::graph_traits<Graph>::vertex_descriptor - сделать оператор () не шаблонным

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...