为什么不能比较自定义类类型的两个向量?

Ita*_*iwa 8 c++ vector

我正在使用向量,A其类类型为其元素类型。我<为我的类定义了关系运算符,但是当我比较其中两个向量时,它就会崩溃。

class A {
    public:
        explicit A(int){}
        bool operator<(const A&)const {
            return true; // for simplicity
        }
};


int main() {

    std::vector<A> v{ A(1), A(2), A(3), A(4), A(5) };
    std::vector<A> v2{ A(0), A(2), A(4), A(6) };

    std::cout << (v < v2) << std::endl; // program crashes here!

}
Run Code Online (Sandbox Code Playgroud)

我试图理解这一点,因为我已经读过STL容器使用元素类型的关系运算符?!

  • 该程序在GCC上运行正常,但在MSVC ++ 14上崩溃,因此我收到断言对话框,抱怨该行 std::cout << (v < v2) << std::endl; // program crashes here!

  • @ user4581301指出的最有趣的事情是,如果我正确定义关系运算符,它将解决此问题:

    class A {
        public:
            explicit A(int) {}
            bool operator<(const A& a)const {
                return x < a.x; // for simplicity
            }
            int x;
    };
    
    Run Code Online (Sandbox Code Playgroud)

现在它可以正常工作,并且程序不会崩溃!MSVC ++中有一些限制吗?(我的意思是正确定义操作员?)

Sla*_*ica 8

我为类“ A”定义了关系运算符<,然后当我创建A对象的向量并比较这两个向量时会崩溃吗?

您在这里选择了一个不好的情况,如果使用的return false;话,那应该没问题,因为它只是意味着的所有实例A都彼此相等。return true;使它成为不好的运算符。

该程序在GCC上运行正常,但在Msvc ++ 14上崩溃

不,它不能正常运行。未定义行为的问题是,在您更改甚至不相关的内容之前,程序似乎无法正常工作的一种不幸行为。就像更改编译器,甚至更改相同或编译器优化级别的版本。

现在它可以正常工作,并且程序不会崩溃!MSVC ++中有一些限制吗?

这不是发生的限制。C ++中的编译器没有义务确保程序员没有创建UB,这是程序员的工作,而不是创建UB,这就是效率的代价。甚至更多的编译器可能会假定没有UB,并且在某些已知情况下,由于这种情况,一些代码已被删除。

  • 也许您可以只添加一行来解释为什么`return true;`使操作员成为坏人。 (2认同)