ошибка: нет соответствующей функции-члена для вызова 'upper_bound' => только в macOS => Windows и Linux в порядке - PullRequest
0 голосов
/ 09 мая 2019

Я собираю код, вдохновленный this , с помощью Qt Creator. Код прекрасно компилируется в Windows 10 и openSUSE Leap 15, но выдает эту ошибку в macOS High Sierra:

error: no matching member function for call to 'upper_bound'
        auto end = band.upper_bound({ 0, last->y + d });
                   ~~~~~^~~~~~~~~~~
/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/include/c++/v1/set:692:14: note: candidate function not viable: cannot convert initializer list argument to 'const std::__1::set<Point, std::__1::less<Point>, std::__1::allocator<Point> >::key_type' (aka 'const Point')
    iterator upper_bound(const key_type& __k)
             ^

Мой заголовок содержит:

#include <algorithm>
#include <cmath>
#include <iostream>

struct Point {
    float x{0}, y{0};

    // Used by the `set<point>` to keep the points in the band
    // sorted by Y coordinates.
    bool operator<(Point const &other) const {
        return y < other.y;
    }

    friend std::ostream &operator<<(std::ostream &os, Point const &p) {
        return os << "(" << p.x << ", " << p.y << ")";
    }

};

Мой источник содержит:

#include <set>

std::pair<Point, Point> nearest_pair(std::vector<Point> points)
{
    std::sort(points.begin(), points.end(),
              [](Point const &a, Point const &b) {
        return a.x < b.x;
    }
    );

    // First and last points from `point` that are currently in the "band".
    auto first = points.cbegin();
    auto last = first + 1;

    // The two closest points we've found so far:
    auto first_point = *first;
    auto second_point = *last;

    std::set<Point> band{ *first, *last };

    float d = dist(*first, *last);

    while (++last != points.end()) {
        while (last->x - first->x > d) {
            band.erase(*first);
            ++first;
        }

        auto begin = band.lower_bound({ 0, last->y - d }); // ERROR line
        auto end = band.upper_bound({ 0, last->y + d });   // ERROR line

        assert(std::distance(begin, end) <= 6);

        for (auto p = begin; p != end; ++p) {
            if (d > dist(*p, *last)) {
                first_point = *p;
                second_point = *last;
                d = dist(first_point, second_point);
            }
        }

        band.insert(*last);
    }
    return std::make_pair(first_point, second_point);
}

Полагаю, мне нужно изменить структуру Point, но я не уверен, как это сделать. Кто-нибудь может помочь?


Обновление

Ошибка была решена путем добавления этих двух конструкторов в структуру Point:

    Point(){

    }

    Point(float x, float y):
        x(x)
      , y(y)
    {

    }

1 Ответ

1 голос
/ 09 мая 2019

Ошибка компилятора ясно объясняет, что ему не удалось неявно создать объект типа Point из списка инициализатора в выражении: band.lower_bound({ 0, last->y - d }). Ошибка допустима, поскольку структура Point не имеет соответствующего пользовательского конструктора для этих аргументов. Чтобы решить эту проблему, вы должны добавить конструктор, который принимает два аргумента с плавающей запятой.

К сожалению, я не отвечаю на вопрос, почему другие компиляторы не жалуются. Вероятно, приложение скомпилировано с различными параметрами.

...