user2975481
user2975481

Reputation: 3

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

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
    }

};

Upvotes: 0

Views: 100

Answers (3)

Niyaz Ivanov
Niyaz Ivanov

Reputation: 667

Your predicate must provide operator like:

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

and specify it as the set's comparator:

std::set<Tuple, Compare> tupleSet;

Upvotes: 1

TerrenceSun
TerrenceSun

Reputation: 473

Use below for operator "<"

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

    return false;
}

Upvotes: 1

WhozCraig
WhozCraig

Reputation: 66194

The default comparator for std::set uses std::less<T>, which requires the object be exposed to an operator < of some form. This will be generally one of two forms:

A free function, like this:

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

or a member function, like this:

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

If you don't want to implement operator < just for use in a std::set you can certainly implement your own binary comparator type directly and use that as the comparator alternative to std::less<T>. Whether you do is your call, and a different solution to a different question (i.e. how to do that, which Niyaz covered in another answer).

Your code, slightly modified to not suck in namespace std and using references where appropriate (you may want to take a look at those, btw, as they will significantly reduce your time spent copying data to and fro).

#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;
}

Upvotes: 1

Related Questions