2012-07-31 64 views
1

好吧,我有1个用户定义的类型,名称为fraction,它代表分子和分母的普通分数。这里是代码:C++ - 排序算法没有看到我的重载“<”运算符为用户定义的类型。

class Fraction 
{ 
private: 
    int numerator; 
    int denominator; 

public: 
    Fraction(int numer,int denom) 
    :numerator(numer),denominator(denom){} 

    int get_denom(){return denominator;} 
    int get_numer(){return numerator;} 
}; 

正如你所看到的,它完全实现在头文件中。

所以我想要做的就是使用排序算法对分数向量进行排序。这里是重载“<”运营商的代码(注:它被放置在同一个文件中Fraction类,但外面的类):

bool operator<(Fraction& first,Fraction& second) 
{ 
    if(first.get_denom() == second.get_denom()) 
    { 
    return first.get_numer()<second.get_numer()?true:false; 
    } 
    int first_num=first.get_denom(); 
    int second_num=second.get_denom(); 
    int lcm=(first_num*second_num)/gcd(first_num,second_num); 
    int first_new_numerator=(lcm/first_num)*first.get_numer(); 
    int second_new_numerator=(lcm/second_num)*second.get_numer(); 

    return first_new_numerator<second_new_numerator?true:false; 
} 

它所做的是检查,如果分母是相等的,如果他们再它测试分子的值。如果它们不相等,则使用最小公倍数和gcd来均衡它们。

当我要使用的排序算法在main(编译时错误)。这里是主要的代码真正的问题开始:

Fraction parse_fraction(string& input) 
{ 

    stringstream fraction_string(input); 
    int numer; 
    fraction_string>>numer; 
    char seperator; 
    fraction_string>>seperator; 
    int denom; 
    fraction_string>>denom; 

    return Fraction(numer,denom); 
} 


int main() 
{ 
    vector<Fraction> fractions; 
    string input; 
    while(cin>>input) 
    { 
    if(input=="|") break; 
    fractions.push_back(parse_fraction(input)); 
    } 

    sort(fractions.begin(),fractions.end); 

    for(int i=0;i<fractions.size();i++) 
    { 
    cout<<fractions[i]; 
    } 

    return 0; 
} 

错误,我得到的是(注:我已经正确重载“< <“运营商的部分,但不希望使杂波这里):

/usr/include/c++/4.6/bits/stl_algo.h||In function ‘_RandomAccessIterator std::__unguarded_partition(_RandomAccessIterator, _RandomAccessIterator, const _Tp&) [with _RandomAccessIterator = __gnu_cxx::__normal_iterator<Fraction*, std::vector<Fraction> >, _Tp = Fraction]’:| 

/usr/include/c++/4.6/bits/stl_algo.h:2253|70|instantiated from ‘_RandomAccessIterator std::__unguarded_partition_pivot(_RandomAccessIterator, _RandomAccessIterator) [with _RandomAccessIterator = __gnu_cxx::__normal_iterator<Fraction*, std::vector<Fraction> >]’| 

/usr/include/c++/4.6/bits/stl_algo.h:2284|54|instantiated from ‘void std::__introsort_loop(_RandomAccessIterator, _RandomAccessIterator, _Size) [with _RandomAccessIterator = __gnu_cxx::__normal_iterator<Fraction*, std::vector<Fraction> >, _Size = long int]’| 

/usr/include/c++/4.6/bits/stl_algo.h:5330|4|instantiated from ‘void std::sort(_RAIter, _RAIter) [with _RAIter = __gnu_cxx::__normal_iterator<Fraction*, std::vector<Fraction> >]’| 

/home/vanio/Desktop/workspace/C++/Ordner/main.cpp:35|43|instantiated from here| 

/usr/include/c++/4.6/bits/stl_algo.h|2212|error: no match for ‘operator<’ in ‘__first.__gnu_cxx::__normal_iterator<_Iterator, _Container>::operator* [with _Iterator = Fraction*, _Container = std::vector<Fraction>, __gnu_cxx::__normal_iterator<_Iterator, _Container>::reference = Fraction&]() < __pivot’| 

/usr/include/c++/4.6/bits/stl_algo.h|2212|note: candidates are:| 

/usr/include/c++/4.6/bits/stl_pair.h|207|note: template<class _T1, class _T2> bool std::operator<(const std::pair<_T1, _T2>&, const std::pair<_T1, _T2>&)| 

/usr/include/c++/4.6/bits/stl_iterator.h|291|note: template<class _Iterator> bool std::operator<(const std::reverse_iterator<_Iterator>&, const std::reverse_iterator<_Iterator>&)| 

/usr/include/c++/4.6/bits/stl_iterator.h|341|note: template<class _IteratorL, class _IteratorR> bool std::operator<(const std::reverse_iterator<_IteratorL>&, const std::reverse_iterator<_IteratorR>&)| 

/usr/include/c++/4.6/bits/basic_string.h|2510|note: template<class _CharT, class _Traits, class _Alloc> bool std::operator<(const std::basic_string<_CharT, _Traits, _Alloc>&, const std::basic_string<_CharT, _Traits, _Alloc>&)| 

/usr/include/c++/4.6/bits/basic_string.h|2522|note: template<class _CharT, class _Traits, class _Alloc> bool std::operator<(const std::basic_string<_CharT, _Traits, _Alloc>&, const _CharT*)| 

/usr/include/c++/4.6/bits/basic_string.h|2534|note: template<class _CharT, class _Traits, class _Alloc> bool std::operator<(const _CharT*, const std::basic_string<_CharT, _Traits, _Alloc>&)| 

/usr/include/c++/4.6/bits/stl_vector.h|1290|note: template<class _Tp, class _Alloc> bool std::operator<(const std::vector<_Tp, _Alloc>&, const std::vector<_Tp, _Alloc>&)| 

/home/vanio/Desktop/workspace/C++/Ordner/Fraction.h|39|note: bool operator<(Fraction&, Fraction&)| 

/home/vanio/Desktop/workspace/C++/Ordner/Fraction.h|39|note: no known conversion for argument 2 from ‘const Fraction’ to ‘Fraction&’| 

/usr/include/c++/4.6/bits/stl_algo.h|2215|error: no match for ‘operator<’ in ‘__pivot < __last.__gnu_cxx::__normal_iterator<_Iterator, _Container>::operator* [with _Iterator = Fraction*, _Container = std::vector<Fraction>, __gnu_cxx::__normal_iterator<_Iterator, _Container>::reference = Fraction&]()’| 

/usr/include/c++/4.6/bits/stl_algo.h|2215|note: candidates are:| 

/usr/include/c++/4.6/bits/stl_pair.h|207|note: template<class _T1, class _T2> bool std::operator<(const std::pair<_T1, _T2>&, const std::pair<_T1, _T2>&)| 

/usr/include/c++/4.6/bits/stl_iterator.h|291|note: template<class _Iterator> bool std::operator<(const std::reverse_iterator<_Iterator>&, const std::reverse_iterator<_Iterator>&)| 

/usr/include/c++/4.6/bits/stl_iterator.h|341|note: template<class _IteratorL, class _IteratorR> bool std::operator<(const std::reverse_iterator<_IteratorL>&, const std::reverse_iterator<_IteratorR>&)| 

/usr/include/c++/4.6/bits/basic_string.h|2510|note: template<class _CharT, class _Traits, class _Alloc> bool std::operator<(const std::basic_string<_CharT, _Traits, _Alloc>&, const std::basic_string<_CharT, _Traits, _Alloc>&)| 

/usr/include/c++/4.6/bits/basic_string.h|2522|note: template<class _CharT, class _Traits, class _Alloc> bool std::operator<(const std::basic_string<_CharT, _Traits, _Alloc>&, const _CharT*)| 

/usr/include/c++/4.6/bits/basic_string.h|2534|note: template<class _CharT, class _Traits, class _Alloc> bool std::operator<(const _CharT*, const std::basic_string<_CharT, _Traits, _Alloc>&)| 

/usr/include/c++/4.6/bits/stl_vector.h|1290|note: template<class _Tp, class _Alloc> bool std::operator<(const std::vector<_Tp, _Alloc>&, const std::vector<_Tp, _Alloc>&)| 

/home/vanio/Desktop/workspace/C++/Ordner/Fraction.h|39|note: bool operator<(Fraction&, Fraction&)| 

/home/vanio/Desktop/workspace/C++/Ordner/Fraction.h|39|note: no known conversion for argument 1 from ‘const Fraction’ to ‘Fraction&’| 
||=== Build finished: 22 errors, 0 warnings ===| 
+0

如果让操作员成为班级成员,会发生什么情况? 'bool operator <(Fraction&second)' – TheSteve 2012-07-31 00:19:02

+4

您应该将'operator <'的参数定义为'const'引用。 – 2012-07-31 00:21:00

+1

两种编码风格建议。 **第一:**而不是'return a?true:false'只是'return a'。 **第二:** gcd正在为这个问题(和缓慢)用大炮杀死苍蝇。只需乘以两个分母即可。你甚至可以跳过检查分母是否相等,这可能会花费更多的CPU周期。 – 2012-07-31 00:21:52

回答

5
bool operator<(Fraction& first,Fraction& second) 

的问题是,你的operator<超载只接受非const参数,但该算法试图将恒定引用与Fraction与您的容器中的元素进行比较。

由于operator<不修改比较对象的内容,就应该带他们通过const引用:

bool operator<(Fraction const & first,Fraction const & second) 
+0

谢谢,这个和海报解决了它 – 2012-07-31 00:45:50

+0

更常见和可读的版本是:bool operator <(const Fraction&first,const Fraction&second); – 2012-07-31 04:31:44

+0

@XanderTulip:那些确切的等价物,以及一个人是否比另一个人更易于阅读。 – 2012-07-31 11:40:37

1

考虑以下代码:

Fraction a, b; 
bool res = (a < b); 

第二行本质上是一个呼叫

bool res = a.operator<(b); 
  1. 如上文建议 - 是const正确性会竭诚为您服务相当不错,在长期运行
  2. 定义成员bool operator<(const Fraction&) const,使分拣实施高兴或只是第一建议上面去 - 是const,正确与bool operator<(const Fraction& a, const Fraction& b)
+0

谢谢,这和上面的海报解决了它 – 2012-07-31 00:45:34

+0

在这种特殊情况下,'operator <'被实现为一个自由函数,所以转换将是'bool res = operator <(a,b);'。此外,通常将二元运算符实现为自由函数(而不是成员函数),提供对于类型的对称性(不允许调用成员函数) – 2012-07-31 02:04:54