本文介绍了在C ++中重载比较运算符导致“无效运算符".的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

当前正在尝试使用C ++对对象的向量进行排序,每个对象都包含一个字符串

Currently attempting to sort a vector of object, with each object containing a string, in C++

字符串可以包含字母或数字(由于设计限制,这是必须的,因为可以更改比较器).

The strings can contain letters or numbers (due to a design constraint, this is necessary, as the comparator can be changed).

此刻,对象的类已重载,因此当比较两个对象时,将比较它们包含的字符串.这一点起作用了—但是,当我使用排序操作(例如STL排序)将对象排序时,它将按顺序对三个字符串进行排序,例如"1","4","12" "1","12","4". 4大于12,但是因为它是从最左位开始比较,所以这种不正确"的排序就会发生.

At the moment, the class of the object is overloaded, so that when two objects are compared, the strings they contain are compared. This works to a point -- however, when I use a sort operation (such as STL sort) to put the objects in order, it will sort three strings such as "1", "4", "12", in the order "1", "12", "4". 4 is greater then 12, but because it begins comparing from the most left digit, this 'incorrect' sort occurs.

我的最初反应是更改比较操作的重载方式.我首先要检查要比较的字符串的长度-如果字符串的内容更大或更小,这将是一个明显的信号.

My initial response was to change how I was overloading the comparison operation. I would first check the length of the string I was comparing -- which would be a telltale sign if the string's contents was larger or smaller.

// overloaded comparision operators
friend bool operator<(const nodeRecord & record1, const nodeRecord & record2){
    // we need to deal with strings of different lengths...
    if(record1.comparator.length() < record2.comparator.length())
        return true;
    else
        return (record1.comparator < record2.comparator);
}

此操作将导致表达式:无效的运算符<".运行时消息.

This operation results in a "Expression: invalid operator<" message during runtime.

关于我在哪里犯错误的任何想法?看来我应该能够准确地指示操作如何进行排序操作-即使该操作无效,因为我当前正在使用向量来包含对象.

Any ideas as to where I am making a mistake? It seems that I should be able to dictate to the operation exactly how I want the sorting operation to occur -- even if it is invalid, since I am currently using a vector to contain the objects.

nodeRecord对象初始化期间的比较器:

Comparator during initialization of the nodeRecord object:

nodeRecord(int fromNode, int toNode, int connectionCost, bool compareByCost = false){
    // take the provided stock information and insert it into the object
    stringstream fromNodeSS;
    fromNodeSS << fromNode;
    this->fromNode = fromNodeSS.str();
    stringstream toNodeSS;
    toNodeSS << toNode;
    this->toNode = toNodeSS.str();
    this->connectionCost = connectionCost;

    // set the comparator to our chosen comparision term
    if (!compareByCost){
        this->comparator = this->fromNode; // we use from node in this case, since we build the tree outwards
    }
    else{
        stringstream ss;
        ss << this->connectionCost;
        this->comparator = ss.str(); // we use the connection cost in this case, to allow us to sort new connections
    }

    // set this as a non-null (active) record
    this->nullRecord = false;
}

推荐答案

您的操作员实际上是无效的.

You operator is effectively invalid.

如果希望运算符<可用于排序,则必须具有许多数学属性.一种是AntiSymmetry属性:

The operator < must have a number of mathematical properties if you want it to be usable for sorting. One is the AntiSymmetry property:

让我们定义x = "b"y = "aa".

  • x < y是因为"b"的长度小于"aa"
  • 的长度
  • y < x,因为"aa"不如"b"
  • x < y because the length of "b" is inferior to the length of "aa"
  • y < x because "aa" is inferior to "b"

哼?

还请注意,如果数字以0为前缀,则您的定义很奇怪.

Also note that your definition is weird for numbers in case they are prefixed by 0s.

哦,比较字符串要比比较数字慢得多.

Oh, and comparing strings is way slower than comparing numbers.

我接受吗?停止更改带有比较信息的节点.实际的比较模式与节点本身无关.

My take ? Stop altering the node with comparison information. The actual comparison mode has nothing to do within the node itself.

然后,您将只编写两种比较方法,一种按成本比较,另一种按来源比较.

Then you'll just write two comparison methods, one that compares by cost and the other by origin.

回到最初的问题,如何编写一个考虑了["a", "b", "aa"]排序的比较器?

And to come back to the original issue, how to write a comparator that consider ["a", "b", "aa"] sorted ?

您快到了,但是长度"比较不完整.仅在长度不同的情况下才需要退回到实际的词法比较,从而忘记了右侧参数的长度小于左侧参数的长度的情况.

You were almost there, but the "length" comparison is incomplete. You need to fall back to the actual lexical comparison only in the case the lengths differ, thus you forgot the case where the right hand side argument's length is inferior to the left hand side's one.

因此正确的格式是,假设有两个字符串:

Thus the correct form is, supposing two strings:

bool compare(std::string const& lhs, std::string const& rhs) {
  if (lhs.length() < rhs.length()) { return true; }
  if (rhs.length() < lhs.length()) { return false; } // don't forget this
  return lhs < rhs;
}

这篇关于在C ++中重载比较运算符导致“无效运算符".的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

07-01 10:05