如何修复与比较器相关的错误?

How to fix an error associating with a comparator?

代码已编译,并且 运行 在 CLion IDE 中没有任何问题,在 MinGW 中使用 g++ 编译器,但是,相同的代码在 Visual Studio IDE 和(MSVC 编译器)

我认为错误应该与以下比较器有关 class:

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

后来被用在:

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

我收到以下错误(只有 VS 2019 (MSVC) 没有错误Clion(MinGW) 中:

File: C:\Program Files (x86)\Microsoft Visual 
Studio19\Community\VC\Tools\MSVC.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_; }
   
};

然后:

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

这是打印出来的:Dijkstra构造运行ning,然后就弹出错误!

任何解决方法?

PS:

  1. 这不是因为“inline”关键字
  2. 该程序在带有 g++ 编译器的 CLion 中完美运行(有或没有复制构造函数和移动构造函数)

你比较奇怪...

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

实际上是这样的:

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

问题在于 >=,特别是该操作的等价包含。那确实 not 强制执行 strict-weak 排序。等价性不应该是任何严格的弱阶比较器的一部分。留给算法利用比较器通过推导来确定,具体来说,当 (a<b)(b<a) 都不为真时,对象被认为是等价的。

因此,您应该使用的比较器很简单:

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

这应该会提供您似乎想要的顺序。