【问题标题】:Trying to use std::find with a vector of custom type objects (C2679, binary '==': no operator, rhs, 'const _Ty'), Visual Studio 15.9.25尝试将 std::find 与自定义类型对象的向量一起使用(C2679,二进制'==':无运算符,rhs,'const _Ty'),Visual Studio 15.9.25
【发布时间】:2020-07-19 08:45:01
【问题描述】:

尊敬的 StackOverflow 社区,

将类型 Couple 定义如下:

class Couple
{
public:
    Couple(Thing* aa, Thing* bb) : a(aa), b(bb) {};
public:
    bool operator == (const Couple& rhs) const { return this->a->unique_id == rhs.a->unique_id && this->b->unique_id == rhs.b->unique_id; }
    bool operator != (const Couple& rhs) const { return this->a->unique_id != rhs.a->unique_id || this->b->unique_id != rhs.b->unique_id; }
    bool operator <= (const Couple& rhs) const { return this->a->unique_id <  rhs.a->unique_id || this->a->unique_id == rhs.a->unique_id && this->b->unique_id <= rhs.b->unique_id; }
    bool operator >= (const Couple& rhs) const { return this->a->unique_id >  rhs.a->unique_id || this->a->unique_id == rhs.a->unique_id && this->b->unique_id >= rhs.b->unique_id; }
    bool operator <  (const Couple& rhs) const { return this->a->unique_id <  rhs.a->unique_id || this->a->unique_id == rhs.a->unique_id && this->b->unique_id <  rhs.b->unique_id; }
    bool operator >  (const Couple& rhs) const { return this->a->unique_id >  rhs.a->unique_id || this->a->unique_id == rhs.a->unique_id && this->b->unique_id >  rhs.b->unique_id; }
    operator Couple() const { return *this; }
public:
    Thing* a;
    Thing* b;
};

我正在尝试使用 c++ std::find 函数:

std::vector<Couple*> generate_couples(std::vector<Thing*> things)
{
    std::vector<Couple*> couples;

    for (unsigned int i = 0; i < things.size(); i++)
    {
        for (unsigned int j = 0; j < things.size(); j++)
        {
            if (things[i] != things[j] && match(things[i], things[j]))
            {
                Couple  c = Couple(things[i], things[j]);
                Couple rc = Couple(things[j], things[i]);

                auto it_c  = std::find(couples.begin(), couples.end(),  c);
                auto it_rc = std::find(couples.begin(), couples.end(), rc);
                if (it_c == couples.end() && it_rc == couples.end())
                    couples.push_back(&c);
            }
        }
    }

    return couples;
}

Visual Studio Community 2017 报错:

错误 C2679 二进制“==”:未找到采用“const _Ty”类型右侧操作数的运算符(或没有可接受的转换)

源自文件的第 3520 行

c:\program files (x86)\microsoft visual studio\2017\community\vc\tools\msvc\14.16.27023\include\xutility

我已经重载了所有比较运算符,包括“==”,我一直在尝试重载 conevrsion 运算符,因为它在错误的最后部分中有所说明。我还尝试在类外定义operator == 并将其声明为友元函数:

bool operator == (const Couple& lhs, const Couple& rhs)
{ return lhs.a->unique_id == rhs.a->unique_id && lhs.b->unique_id == rhs.b->unique_id; }
class Couple
{
    // ...
    friend bool operator == (const Couple& lhs, const Couple& rhs); 
    // ...
};

它会引发错误:

E0344 这个算子函数的参数太多

有几个相关的问题,最相似的一个是这个(How to use std::find/std::find_if with a vector of custom class objects?),但我在那里找不到我的问题的解决方案。

提前感谢任何 cmets 和答案!

【问题讨论】:

  • couples.push_back(&amp;c); -- 像这样存储局部变量的地址是未定义的行为。在循环的下一次迭代中会发生什么,当 c 你的地址要么被回收,要么在一阵烟雾中消失并消失?
  • 无关:operator Couple() const { return *this; } 永远不会被使用,因此您可以将其删除。
  • 同样,但不相关,当重载关系运算符时,您真正需要完全实现的只是运算符&lt; 和==。所有其他的都可以用&lt; 和== 来实现。这样做的原因是,如果&lt; 和== 很复杂,那么您不会试图弄清楚如何将事情从里到外来实现!=、&gt;= 等。例如:@ 987654341@ 比试图以困难的方式反转 == 的错误要容易得多。
  • Here is an example of the relational operators。请注意所有其他运算符的简化,而不是试图找出逆运算。
  • 哇,谢谢@PaulMcKenzie!这是有道理的:)

标签: c++ find operator-overloading


【解决方案1】:

所以我认为你有几个问题,但最根本的是这个

std::vector<Couple*> couples;

你有一个Couple 指针的向量。 Couple 类的任何重载运算符都无法帮助您在指针向量中查找内容。

您遇到的另一个问题是将指向本地范围对象的指针推送到向量上。当这些对象超出范围时(每次循环都会发生这种情况),它们会被销毁,并在向量中留下指向无效对象的指针。

因此,显而易见的第一步是使用vector&lt;Couple&gt; 而不是vector&lt;Couple*&gt;。如果您觉得必须使用指针向量,那么您将不得不开始使用 new 分配对象,并按照 MakeCAT 的建议使用各种 find_if。

我对@9​​87654327@ 错误没有任何解释。从发布的代码中不应该发生这种情况。所以可能你犯了一些从上面的代码中看不到的错误。

【讨论】:

  • 感谢您的详细解释!我确实认为vector&lt;Couple*&gt; 可能会导致问题,但专注于错误并且对此视而不见。我认为我确实需要从该函数返回一个指针向量。因此,如果我使用运算符new 动态分配Couple 对象,那么在程序离开此函数的范围后,向量中的指针应该保持有效,不是吗?
  • @LevPleshkov 没错,它们将一直有效,直到您删除它们。当然,危险是您永远不会删除它们,或者您将多次删除它们。出于这样的原因,建议使用智能指针而不是原始指针。使用智能指针,删除会自动发生。
【解决方案2】:

您正在使用指向Couple 的指针 向量,因此Couple 中定义的运算符不能直接从std::find 使用。

您可以使用std::find_if 使其取消引用指针并使用Couple 中的运算符。

auto it_c  = std::find_if(couples.begin(), couples.end(), [&](auto p){ return *p == c; });
auto it_rc = std::find_if(couples.begin(), couples.end(), [&](auto p){ return *p == rc; });

【讨论】:

  • 不幸的是,他还有另一个错误是将指向本地对象的指针推到向量上。
  • 谢谢你的解释和有用的sn-p :)
猜你喜欢
  • 2011-10-19
  • 1970-01-01
  • 1970-01-01
  • 2013-04-17
  • 2020-08-10
  • 2013-05-02
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多