C++: candidate function not viable: no known conversion from 'Segment [2]' to 'int *' for 1st argument

Vishal Rana

This the C++ code for the sweeping line algorithm that I am using. I am using HeapSort to sort the points. But I am getting the below 2 errors:

Line 214: Char 5: error: no matching function for call to 'heapSort'

heapSort(arr, n);

Line 134: Char 6: note: candidate function not viable: no known conversion from 'Segment [2]' to 'int *' for 1st argument

void heapSort(int arr[], int n)

1 error generated.

I am not exactly why it is throwing the 2 errors.

// Implementation of Sweep Line Algorithm
#include <bits/stdc++.h>
using namespace std;

// A point in 2D plane
struct Point
{
    int x, y;
};

// A line segment with left as Point
// with smaller x value and right with
// larger x value.
struct Segment
{
    Point left, right;
};


// An event for sweep line algorithm
// An event has a point, the position
// of point (whether left or right) and
// index of point in the original input
// array of segments.
struct Event {
    int x, y;
    bool isLeft;
    int index;

    Event(int x, int y, bool l, int i) : x(x), y(y), isLeft(l), index(i) {}

    // This is for maintaining the order in set.
    bool operator<(const Event& e) const {
            return y < e.y;
    }
};


// Given three colinear points p, q, r, the function checks if
// point q lies on line segment 'pr'
bool onSegment(Point p, Point q, Point r)
{
    if (q.x <= max(p.x, r.x) && q.x >= min(p.x, r.x) &&
        q.y <= max(p.y, r.y) && q.y >= min(p.y, r.y))
    return true;
    
    return false;
}
    
// To find orientation of ordered triplet (p, q, r).
// The function returns following values
// 0 --> p, q and r are colinear
// 1 --> Clockwise
// 2 --> Counterclockwise
int orientation(Point p, Point q, Point r)
{
    // See https://www.geeksforgeeks.org/orientation-3-ordered-points/
    // for details of below formula.
    int val = (q.y - p.y) * (r.x - q.x) -
            (q.x - p.x) * (r.y - q.y);
    
    if (val == 0) return 0; // colinear
    
    return (val > 0)? 1: 2; // clock or counterclock wise
}
    
// The main function that returns true if line segment 'p1q1'
// and 'p2q2' intersect.
bool doIntersect(Segment s1, Segment s2)
{
    Point p1 = s1.left, q1 = s1.right, p2 = s2.left, q2 = s2.right;
    
    // Find the four orientations needed for general and
    // special cases
    int o1 = orientation(p1, q1, p2);
    int o2 = orientation(p1, q1, q2);
    int o3 = orientation(p2, q2, p1);
    int o4 = orientation(p2, q2, q1);
    
    // General case
    if (o1 != o2 && o3 != o4)
        return true;
    
    // Special Cases
    // p1, q1 and p2 are colinear and p2 lies on segment p1q1
    if (o1 == 0 && onSegment(p1, p2, q1)) return true;
    
    // p1, q1 and q2 are colinear and q2 lies on segment p1q1
    if (o2 == 0 && onSegment(p1, q2, q1)) return true;
    
    // p2, q2 and p1 are colinear and p1 lies on segment p2q2
    if (o3 == 0 && onSegment(p2, p1, q2)) return true;
    
    // p2, q2 and q1 are colinear and q1 lies on segment p2q2
    if (o4 == 0 && onSegment(p2, q1, q2)) return true;
    
    return false; // Doesn't fall in any of the above cases
}


// Find predecessor of iterator in s.
auto pred(set<Event> &s, set<Event>::iterator it) {
    return it == s.begin() ? s.end() : --it;
}

// Find successor of iterator in s.
auto succ(set<Event> &s, set<Event>::iterator it) {
    return ++it;
}
void heapify(int arr[], int n, int i)
{
    int largest = i; // Initialize largest as root
    int l = 2 * i + 1; // left = 2*i + 1
    int r = 2 * i + 2; // right = 2*i + 2
 
    // If left child is larger than root
    if (l < n && arr[l] > arr[largest])
        largest = l;
 
    // If right child is larger than largest so far
    if (r < n && arr[r] > arr[largest])
        largest = r;
 
    // If largest is not root
    if (largest != i) {
        swap(arr[i], arr[largest]);
 
        // Recursively heapify the affected sub-tree
        heapify(arr, n, largest);
    }
}
 
// main function to do heap sort
void heapSort(int arr[], int n)
{
    // Build heap (rearrange array)
    for (int i = n / 2 - 1; i >= 0; i--)
        heapify(arr, n, i);
 
    // One by one extract an element from heap
    for (int i = n - 1; i > 0; i--) {
        // Move current root to end
        swap(arr[0], arr[i]);
 
        // call max heapify on the reduced heap
        heapify(arr, i, 0);
    }
}
// Returns true if any two lines intersect.
bool isIntersect(Segment arr[], int n)
{
    // Pushing all points to a vector of events
    vector<Event> e;
    for (int i = 0; i < n; ++i) {
        e.push_back(Event(arr[i].left.x, arr[i].left.y, true, i));
        e.push_back(Event(arr[i].right.x, arr[i].right.y, false, i));
    }
    
    // Sorting all events according to x coordinate.
    sort(e.begin(), e.end(), [](Event &e1, Event &e2) {return e1.x < e2.x;});
    
    // For storing active segments.
    set<Event> s;
    
    // Traversing through sorted points
    for (int i=0; i<2*n; i++)
    {
        Event curr = e[i];
        int index = curr.index;
        
        // If current point is left of its segment
        if (curr.isLeft)
        {
            // Get above and below points
            auto next = s.lower_bound(curr);
            auto prev = pred(s, next);
            
            // Check if current point intersects with
            // any of its adjacent
            if (next != s.end() && doIntersect(arr[next->index], arr[index]))
            return true;
            if (prev != s.end() && doIntersect(arr[prev->index], arr[index]))
            return true;
                
            // Insert current point (or event)
            s.insert(curr);
        }
        
        // If current point is right of its segment
        else
        {
            // Find the iterator
            auto it = s.find(curr);
            
            // Find above and below points
            auto next = succ(s, it);
            auto prev = pred(s, it);
            
            // If above and below point intersect
            if (next != s.end() && prev != s.end())
            if (doIntersect(arr[prev->index], arr[next->index]))
                return true;
            
            // Return current point
            s.erase(curr);      
        }
    }
    return false;
}
// Driver code
int main() {
    Segment arr[] = { {{0, 0}, {0, 4}}, {{1, 0}, {5, 0}}};
    int n = sizeof(arr)/sizeof(arr[0]);
    heapSort(arr, n);
    cout << isIntersect(arr, n);
    return 0;
}
Vlad from Moscow

The function heapSort is declared like

void heapSort(int arr[], int n);

that is its first parameter has the type int arr[] that is adjusted by the compiler to the type int *.

But you are calling the function passing an array of the type Segment[2] as the first argument

Segment arr[] = { {{0, 0}, {0, 4}}, {{1, 0}, {5, 0}}};
int n = sizeof(arr)/sizeof(arr[0]);
heapSort(arr, n);

And there is no implicit conversion from the type Segment[2] (the type of the array arr used as a function argument) to the type int * (the type of the first parameter of the function) after adjusting the type of the first parameter int[] to the type int * implicitly by the compiler.

One of solutions is to rewrite the function heapSort as a template function for example like

template <typename T>
void heapSort( T arr[], int n);

In this case you will need to rewrite other functions that are used by the function heapSort also as template functions,

Collected from the Internet

Please contact [email protected] to delete if infringement.

edited at
0

Comments

0 comments
Login to comment

Related