Follow

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use
Contact

How to fix an error associating with a comparator?

The code is compiled, and run without any issue in CLion IDE with g++ compiler in MinGW, however, the same exact code has a compilation error in Visual Studio IDE and with (MSVC compiler)

I believe the error should have to do with the follwoing comparator class:

struct CompareVertices {
    inline bool operator()(shared_ptr<Vertex> a, shared_ptr<Vertex> b) const {
        return a->get_distance() < b->get_distance() ? false : true;
    }
};

which later has been made use of in:

MEDevel.com: Open-source for Healthcare and Education

Collecting and validating open-source software for healthcare, education, enterprise, development, medical imaging, medical records, and digital pathology.

Visit Medevel

 priority_queue<shared_ptr<Vertex>, vector<shared_ptr<Vertex>>, CompareVertices> pQ;

I get the following error (Only in VS 2019 (MSVC) and no error in Clion(MinGW)):

File: C:\Program Files (x86)\Microsoft Visual 
Studio\2019\Community\VC\Tools\MSVC\14.29.30133\include\xutility
Line: 1520
Expression: invalid comparator

For information on how your program can cause an assertion
failure, see the Visual C++ documentation on asserts.

(Press Retry to debug the application)
'practice_Classes.exe' (Win32): Loaded 'C:\Windows\System32\kernel.appcore.dll'. 
'practice_Classes.exe' (Win32): Loaded 'C:\Windows\System32\msvcrt.dll'. 
'practice_Classes.exe' (Win32): Loaded 'C:\Windows\System32\rpcrt4.dll'. 
'practice_Classes.exe' (Win32): Loaded 'C:\Windows\System32\user32.dll'. 
'practice_Classes.exe' (Win32): Loaded 'C:\Windows\System32\win32u.dll'. 
'practice_Classes.exe' (Win32): Loaded 'C:\Windows\System32\gdi32.dll'. 
'practice_Classes.exe' (Win32): Loaded 'C:\Windows\System32\gdi32full.dll'. 
'practice_Classes.exe' (Win32): Loaded 'C:\Windows\System32\msvcp_win.dll'. 
'practice_Classes.exe' (Win32): Loaded 'C:\Windows\System32\ucrtbase.dll'. 
'practice_Classes.exe' (Win32): Loaded 'C:\Windows\System32\imm32.dll'. 
'practice_Classes.exe' (Win32): Loaded 'C:\Windows\System32\TextShaping.dll'. 
'practice_Classes.exe' (Win32): Loaded 'C:\Windows\System32\uxtheme.dll'. 
'practice_Classes.exe' (Win32): Loaded 'C:\Windows\System32\combase.dll'. 
'practice_Classes.exe' (Win32): Loaded 'C:\Windows\System32\msctf.dll'. 
'practice_Classes.exe' (Win32): Loaded 'C:\Windows\System32\oleaut32.dll'. 
'practice_Classes.exe' (Win32): Loaded 'C:\Windows\System32\sechost.dll'. 
'practice_Classes.exe' (Win32): Loaded 'C:\Windows\System32\bcryptprimitives.dll'. 
'practice_Classes.exe' (Win32): Loaded 'C:\Windows\System32\TextInputFramework.dll'. 
'practice_Classes.exe' (Win32): Loaded 'C:\Windows\System32\CoreMessaging.dll'. 
'practice_Classes.exe' (Win32): Loaded 'C:\Windows\System32\CoreUIComponents.dll'. 
'practice_Classes.exe' (Win32): Loaded 'C:\Windows\System32\SHCore.dll'. 
'practice_Classes.exe' (Win32): Loaded 'C:\Windows\System32\ws2_32.dll'. 
'practice_Classes.exe' (Win32): Loaded 'C:\Windows\System32\ntmarta.dll'. 
'practice_Classes.exe' (Win32): Loaded 'C:\Windows\System32\advapi32.dll'. 
'practice_Classes.exe' (Win32): Loaded 'C:\Windows\System32\WinTypes.dll'. 

Network.h

using namespace std;
typedef long double ld;
class Arc; // forward declaration

class Vertex {

private:
    string name_{ "" };
    long double dist_{ numeric_limits<long double>::infinity() }; 
    shared_ptr<Vertex> prev_{ nullptr };
    bool visited_{ false };
    vector<shared_ptr<Vertex>> adjacent_vertices_;
    vector<shared_ptr<Arc>> adjacent_arcs_;

public:

    Vertex() = default;
    Vertex(string name) : name_(name)
    {
    }
    ~Vertex() = default;


    Vertex(const Vertex& cpyObj) :
        name_(cpyObj.name_),
        dist_(cpyObj.dist_),
        visited_(cpyObj.visited_),
        adjacent_vertices_(cpyObj.adjacent_vertices_),
        adjacent_arcs_(cpyObj.adjacent_arcs_)
    {
        prev_ = make_shared<Vertex>(name_);
    }

    Vertex(Vertex&& moveObj) noexcept :
        name_(move(moveObj.name_)),
        dist_(move(moveObj.dist_)),
        prev_(move(moveObj.prev_)),
        visited_(move(moveObj.visited_)),
        adjacent_vertices_(move(moveObj.adjacent_vertices_)),
        adjacent_arcs_(move(moveObj.adjacent_arcs_))
    {
        moveObj.prev_ = nullptr;
    }


    // some setter and getter functions  including the follwoing two:
    inline void set_prev(shared_ptr<Vertex> ptr) { this->prev_ = ptr; }
    inline auto get_prev() const { return prev_; }
   
};

then:

struct CompareVertices {
    bool operator()(shared_ptr<Vertex> a, shared_ptr<Vertex> b) const {
        return a->get_distance() < b->get_distance() ? false : true;
    }
};


class Arc {

private:
    shared_ptr<Vertex> from_{ nullptr };
    shared_ptr<Vertex> to_{ nullptr };
    long double arc_length_{ 0 };

public:

Arc() = default;
Arc(shared_ptr<Vertex> from, shared_ptr<Vertex> to, long double length) : arc_length_(length)
{
    this->from_ = from;
    this->to_ = to;
}
~Arc() = default;

// some setter and getter and output stream functions here   
};

class Network {

private:

    vector<shared_ptr<Vertex>> Vertices_;
    vector<shared_ptr<Arc>> Arcs_;

public:

    Network() = default;
    Network(vector<shared_ptr<Vertex>>& Vertices, vector<shared_ptr<Arc>>& Arcs) : Vertices_(Vertices), Arcs_(Arcs) {}
    ~Network() = default;

// also some setter and getter plus some other utility functions here

};



class Dijkstras_Alg
{
private:
    shared_ptr<Vertex> source_node_{ nullptr };
    shared_ptr<Vertex> destin_node_{ nullptr };
    shared_ptr<Network> Ntwk_{ nullptr };

public:

    Dijkstras_Alg() = default;
    Dijkstras_Alg(shared_ptr<Vertex> src, shared_ptr<Vertex> destin, shared_ptr<Network> Ntwk) {
        cout << "Dijkstra construction running\n";
        this->source_node_ = src;
        this->destin_node_ = destin;
        this->Ntwk_ = Ntwk;
    }
    ~Dijkstras_Alg() = default;

// some setter and getter and utility functions here 

    void compute_path() {
        std::priority_queue< std::shared_ptr<Vertex>, std::vector<shared_ptr<Vertex> >, CompareVertices > pQ;
        source_node_->set_distance(0);
        pQ.push(source_node_);
        while (!pQ.empty())
        {
                    // arcs relaxation is done here
                pQ.pop();
                current_vertex->set_visited();
            }
    
        }  
    };

enter image description here

enter image description here

this is printed: Dijkstra construction running, and then the error is popping up!

Any workaround?

PS:

  1. it is not due to "inline" keyword
  2. the program works perfectly in CLion with g++ compiler (with or without the copy constructor and move constructor)

>Solution :

Your somewhat odd comparator…

return a->get_distance() < b->get_distance() ? false : true;

is effectively this:

return a->get_distance() >= b->get_distance();

The problem is that >=, and specifically the equivalence inclusion of that operation. That does not enforce a strict-weak ordering. Equivalence should not be a part of any strict weak order comparator. That is left to the algorithm utilizing the comparator to determine by derivation, specifically when neither (a<b) nor (b<a) are true, the objects are considered equivalent.

Therefore, the comparator you should be using is simple this:

return b->get_distance() < a->get_distance();

That should provide the ordering you seem to want.

Add a comment

Leave a Reply

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use

Discover more from Dev solutions

Subscribe now to keep reading and get access to the full archive.

Continue reading