set<>类,当我插入类时,它不接受我的<运算符

set<> class, when I insert into the class, it doesn't accept my < operator

本文关键字:lt 不接受 运算符 我的 gt set 插入      更新时间:2023-10-16
class Tuple
{
private:
    vector<string> values;
public:
    Tuple(vector<Parameter> newValues)
    {
        for(int i = 0; i < newValues.size(); i++)
        {
            string val = newValues[i].getValue();
            values.push_back(val);
        }
    }
    Tuple(vector<string> newAttributes)
    {
        values = newAttributes;
    }
    ~Tuple()
    {
    }
    bool operator < (Tuple &tup)
    {
        if(values < tup.getStringVec())
            return true;
        return false;
    }
    bool operator <= (Tuple &tup)
    {
        if(values <= tup.getStringVec())
            return true;
        return false;
    }
    bool operator > (Tuple &tup)
    {
        if(values > tup.getStringVec())
            return true;
        return false;
    }
    bool operator >= (Tuple &tup)
    {
        if(values >= tup.getStringVec())
            return true;
        return false;
    }
};

class Relation
{
private:
    set<Tuple> tupleSet;
public:
    Relation():
    {
    }
    ~Relation()
    {
    }
    void addToTupleSet(Tuple newTuple)
    {
        tupleSet.insert(newTuple); //<<this causes the problem
    }
};

std::set的默认比较器使用 std::less<T> ,这要求对象暴露在某种形式的operator <中。这通常是以下两种形式之一:

一个自由函数,像这样:

bool operator <(const Tuple& arg1, const Tuple& arg2);

或成员函数,如下所示:

class Tuple
{
public:
    bool operator <(const Tuple& arg) const
    {
        // comparison code goes here
    }
};

如果您不想实现operator <只是为了在std::set中使用,您当然可以直接实现自己的二进制比较器类型,并将其用作std::less<T>的比较器替代方案。你是否这样做是你的决定,也是对不同问题的不同解决方案(即如何做到这一点,Niyaz 在另一个答案中涵盖了这个问题)。

您的代码,稍微修改一下,以免吸入命名空间std并在适当的地方使用引用(顺便说一句,您可能想看看这些代码,因为它们将显着减少您来回复制数据所花费的时间)。

#include <iostream>
#include <string>
#include <iterator>
#include <vector>
#include <set>
// I added this, as your source included no such definition 
class Parameter
{
public:
    Parameter(const std::string s) : s(s) {}
    const std::string& getValue() const { return s; }
private:
    std::string s;
};
class Tuple
{
private:
    std::vector<std::string> values;
public:
    Tuple(const std::vector<Parameter>& newValues)
    {
        for(auto val : newValues)
            values.push_back(val.getValue());
    }
    Tuple(const std::vector<std::string>& newAttributes)
        : values(newAttributes)
    {
    }
    // note const member and parameter. neither the passed object nor
    //  this object should be modified during a comparison operation.
    bool operator < (const Tuple &tup) const
    {
        return values < tup.values;
    }
};

class Relation
{
private:
    std::set<Tuple> tupleSet;
public:
    void addToTupleSet(const Tuple& tup)
    {
        tupleSet.insert(tup);
    }
};
int main(int argc, char *argv[])
{
    Tuple tup({"a","b","c"});
    Relation rel;
    rel.addToTupleSet(tup);
    return 0;
}
下面

用于运算符"<"

bool operator < (const Tuple &tup) const
{
    /*if(values < tup.getStringVec())
        return true;*/             //getStringVec undefined, so comment out temporarily
    return false;
}

您的谓词必须提供如下运算符:

struct Compare
{
    bool operator() ( const T1& lhs, const T2& rhs )
    {
        // here's the comparison logic
        return bool_value;
    }
};

并将其指定为集合的比较器:

std::set<Tuple, Compare> tupleSet;