Использование gsl::span с range-v3

Я попробовал небольшой пример, чтобы привыкнуть к библиотекам GSL и range-v3, и мне стало интересно, как они могут работать вместе. У меня есть эта игрушка, например

#include <iostream>
#include <range/v3/all.hpp>

using namespace std;
using namespace ranges;

void example_vector(vector<int> const& v)
{
  ranges::for_each(view::tail(v), [](int x){
    cout << x << ' ';
  });
  cout << '\n';
}

int main()
{
   auto seq = vector<int> { 2,2,2,0,0,2,1,2 };
   example_vector(seq);
}

который работает. Но если я попытаюсь использовать gsl::span<int> в качестве диапазона, это приведет к сообщению об ошибке. Компилятор говорит мне, что span не соответствует концепции представления.

#include <gsl.h>

// ...

void example_span(gsl::span<const int> v)
{
  ranges::for_each(view::tail(v), [](int x){
    cout << x << ' ';
  });
  cout << '\n';
}

Сообщение компилятора:

note: candidate template ignored: disabled by 'enable_if'
      [with Rng = gsl::span<const int, -1> &, Rest = <>, _concept_requires_123 = 42]
                    CONCEPT_REQUIRES_(ViewConcept<Rng, Rest...>())>

Но, насколько я понимаю, так и должно быть, поскольку span является конкретным представлением и даже имеет итераторы begin() и end() (одного и того же типа).

  • Разве не было бы здорово, если бы они работали вместе, будучи компонуемыми, или есть какие-то причины, по которым они несовместимы?
  • Я думаю, что это проблема, которая возникает из-за сильного использования «концепции» в range-v3. Решается ли она автоматически, если язык поддерживает какую-то другую концептуальную функцию?
  • Я предполагаю, что span в настоящее время нуждается в некоторой адаптации, если я хочу использовать обе библиотеки вместе в каком-то (непромышленном) программном обеспечении. Что я должен изменить, чтобы они работали вместе? (если это вообще хорошая идея)
  • Это также в конечном итоге приводит меня к вопросу: «Какой класс должен быть заполнен для работы с range-v3?» Является ли наследование от фасадов, адаптеров и т. д. единственным способом сообщить компилятору об этих концептуальных требованиях?

person Maikel    schedule 26.03.2016    source источник
comment
Посетите страницу проблем gsl github. Сейчас много проблем с итераторами, и они будут полностью переписаны. ИМО, он сейчас не в состоянии готовности к производству.   -  person Nicolas Holthaus    schedule 26.03.2016
comment
Можете ли вы указать на проблему, которая непосредственно связана с моей проблемой? Я прошел около 40 выпусков, но, возможно, я не все понял ;^). Я даже не могу заставить итераторы работать с любой функцией range-v3.   -  person Maikel    schedule 26.03.2016
comment
Извините, я имел ввиду вообще много проблем, не то чтобы там было решение.   -  person Nicolas Holthaus    schedule 26.03.2016


Ответы (1)


Концепция View в range-v3 (и диапазоны TS, если уж на то пошло) требует, чтобы тип R удовлетворял обеим концепциям Range -- begin(r) и end(r) ограничивают диапазон итератора -- а концепция Semiregular -- R должна быть копируемой/перемещаемой. конструируемое копирование/перемещение назначаемое и конструируемое по умолчанию. Итераторы и сторожевые типы Range (что возвращают begin и end) также должны быть Semiregular (среди прочих требований).

Семейство span не удовлетворяет концепции View, поскольку span в некоторых случаях не являются конструируемыми по умолчанию, а их итераторы ни в каких случаях не конструируются по умолчанию. Поскольку даже стандартный C++ требует конструкции по умолчанию для итераторов Forward, текущие итераторы span не соответствуют ни Ranges TS, range-v3, ни Standard C++.

Тем не менее, изменения, необходимые для удовлетворения всех этих семейств требований, минимальны и просты. .

20161207 Обновление:

range-v3 теперь содержит реализацию span, которая правильно моделирует концепции View/Range.

20170128 Обновление:

gsl::span теперь имеет конструктивные итераторы по умолчанию. Следовательно, интервалы теперь можно использовать с range-v3. Пролеты с динамическим экстентом (например, gsl::span<int>) моделируют концепции Range и View, а пролеты с статическим экстентом (например, gsl::span<int, 42>) моделируют только Range, поскольку они не соответствуют требованию View для построения по умолчанию.

person Casey    schedule 29.03.2016
comment
Спасибо за это понимание и репозиторий! - person Maikel; 29.03.2016