2013-11-10 4 views
0
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 
    } 

}; 
+1

И "не принимает", что вы имеете в виду? Какое сообщение об ошибке вы получаете? –

+2

Ваш оператор должен быть 'const', как в' bool operator <(const Tuple &) const', и fyi, единственный, который вам нужно реализовать для 'std :: set', -' operator <', поскольку он использует строгий слабый порядок, а '! (a WhozCraig

+0

Но если вы собираетесь его реализовать, вы должны реализовать их все. Если 'operator <' имеет смысл для вашего класса, то и все остальные операторы сравнения. И если 'operator <' * не имеет смысла для вашего класса, тогда вы не должны реализовывать его только для удовлетворения 'std :: set', вы должны использовать отдельный, именованный компаратор, имя которого описывает его функцию. –

ответ

1

по умолчанию компаратор для 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>. Если вы делаете это ваш звонок и другое решение другого вопроса (например, как это сделать, что Нияз рассмотрел в другом ответе).

Ваш код, слегка измененный, чтобы не всасывать пространство имен 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; 
} 
1

Ваш предикат должен предоставить оператору, как:

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

и указать его в качестве компаратора множества в:

std::set<Tuple, Compare> tupleSet; 
1

Использование ниже для оператора "<"

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

    return false; 
} 
Смежные вопросы