Reputation: 83
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:
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();
}
}
};
this is printed: Dijkstra construction running, and then the error is popping up!
Any workaround?
PS:
Upvotes: 3
Views: 403
Reputation: 66244
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.
Upvotes: 3