2013-11-10 35 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>的替代比较器。无论你做的是你的呼叫,还是另一个不同问题的解决方案(即如何做到这一点,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; 
} 
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; 
}