Проблема с использованием std :: function в operator = - PullRequest
0 голосов
/ 10 апреля 2020

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

iterator(std::pair<T, std::function<T(T&)>> rhs, const std::function<bool(T&, T&)> cmp): 
        base(rhs), cmp(cmp), gen(range<T>::gen_function(rhs)) {}

далее ... я пытаюсь использовать функтор cmp в операторе ==:

bool operator==(const iterator& rhs) const { return cmp(**this, *rhs); }
bool operator!=(const iterator& rhs) const { return !cmp(**this, *rhs); }

с помощью clang ++ (v 11.0.0, Ubuntu 18)

clang++ -std=c++2a -stdlib=libc++ coroutins_iterator.cpp -v

и компилятор выдаёт мне ошибку:

./coroutins_iterator.h:52:56: error: no matching function for call to object of type 'const std::function<bool (int &, int &)>'
            bool operator!=(const iterator& rhs) const { return !cmp(**this, *rhs); }
                                                                 ^~~
coroutins_iterator.cpp:31:14: note: in instantiation of member function 'range<int>::iterator::operator!=' requested here
    for (auto a : range<int>(2, 10, [](int &a){ return a * 2; })) {
                ^
/usr/include/c++/v1/functional:2342:9: note: candidate function not viable: expects an l-value for 1st argument
_Rp operator()(_ArgTypes...) const;

как это исправить?

или .. я могу сделать этот интерфейс другим способом?

1 Ответ

3 голосов
/ 10 апреля 2020
T operator*() const { return gen.current_num(); }

const std::function<bool(T&, T&)> cmp

cmp(**this, *rhs);

Проблема есть. Сообщение об ошибке объясняет это:

ошибка: нет функции сопоставления для вызова ... функция-кандидат недопустима: ожидает l-значение для 1-го аргумента

cmp принимает неконстантную ссылку lvalue. Оператор косвенного обращения возвращает значение. Неконстантные lvalue-ссылки не могут быть привязаны к rvalues.

Вы можете либо:

  • Изменить оператор косвенного обращения, чтобы он возвращал неконстантную lvalue-ссылку (это должна быть неконстантная постоянная функция-член). Неконстантный аргумент ссылки lvalue может связываться с неконстантными lvalue.
  • Или изменить оболочку функции, чтобы вместо нее принимать константную ссылку. Const lvalue ссылки могут связываться с prvalues.
...