如何在包含类的向量中使用std :: less

时间:2012-11-23 13:23:57

标签: c++

如何在包含类的向量中使用std :: less,所有google结果都使用普通的int示例。

当涉及到课程时,例如:

class A{
   public:
      A( int value = 0 ):m_value(value){};
      int m_value;
};

如何做以下事情:

std::count_if( m_cells.begin(), m_cells.end(), std::less< int >() );

Less会收到A,而不是int。 std::less< A >

似乎更少需要一个仿函数operator()(),如何避免这种情况?我需要实现operator&lt;(int a)?结合?还有什么?

代码:

  1 #include <iostream>
  2 #include <vector>
  3 #include <algorithm>
  4
  5 using namespace std;
  6
  7 class A
  8 {
  9    public:
 10       A(int a = 0 ):m_value(a) {}
 11       bool operator!=( int a )
 12       {
 13          return m_value != a;
 14       }
 15
 16       bool operator<( A &a )
 17       {
 18          return m_value < a.m_value;
 19       }
 20
 21       int m_value;
 22 };
 23
 24
 25 int main(){
 26    std::vector< A > m_cells( 5 );
 27
 28    m_cells[2].m_value = 3;
 29    m_cells[3].m_value = 4;
 30    m_cells[4].m_value = 4;
 31    std::count_if( m_cells.begin(), m_cells.end(), std::less< A >() );
 32    return 0;
 33 }
 34

这导致:

/usr/lib/gcc/x86_64-redhat-linux/4.4.6/../../../../include/c++/4.4.6/bits/stl_algo.h:4437: error: no match for call to ‘(std::less<A>) (A&)’
/usr/lib/gcc/x86_64-redhat-linux/4.4.6/../../../../include/c++/4.4.6/bits/stl_function.h:229: note: candidates are: bool std::less<_Tp>::operator()(const _Tp&, const _Tp&) const [with _Tp = A]

3 个答案:

答案 0 :(得分:2)

operator<实施A,然后传入std::less<A>,其他选项(例如,您可以将转化运营商实施为int - YUCKYUCKYUCKYUCK)

编辑:继续......

就像詹姆斯所说,std::less<>需要两个参数,如果你被卡在c ++ 03上(并且没有提升),你可以做类似以下的事情:

std::count_if( m_cells.begin(), m_cells.end() ,std::bind1st(std::less<A>(), 3) )

基本上其中一个参数绑定到3 - 这是第一个参数(考虑左侧),你也可以绑定到第二个参数(右侧 - 使用std::bind2nd),取决于您希望谓词如何工作。

这种方法要求您正确实施operator<,即

bool operator<(A const& a) const
{
}

EDIT2:对于c ++ 11,您可以尝试以下任何一种方法:

 std::cout << std::count_if( m_cells.begin(), m_cells.end() , [](A const& a) { return 3 < a.m_value; } ) << std::endl; // lambda
 std::cout << std::count_if( m_cells.begin(), m_cells.end() , std::bind(std::less<A>(), _1, 4) ) << std::endl; // bind second argument (rhs)
 std::cout << std::count_if( m_cells.begin(), m_cells.end() , std::bind(std::less<A>(), 3, _1) ) << std::endl; // bind first argument (lhs)

答案 1 :(得分:2)

您需要的不仅仅是std::less,即使它是int的向量。 std::count_if使用单个参数调用谓词; std::less 需要两个。

还有许多其他功能对象 std::bind2nd可以合并。找出正确的 然而,组合并不是微不足道的,结果都是不可读的 而且很脆弱,所以这不是我推荐的解决方案。如果你正在使用 C ++ 11,有lamba,这显然是要走的路。除此以外, boost :: bind非常实用;如果你不能使用Boost,那就是唯一的 合理的解决方案是编写自己的谓词对象, 类似的东西:

class ALessThan
{
    int myUpperLimit;
public:
    ALessThan( int upperLimit ) : myUpperLimit( upperLimit ) {}
    bool operator()( A const& object ) const
    {
        return object.m_value < myUpperLimit;
    }
};

(请注意,无论你怎么做,你都必须提供一个 谓词的参数。少于什么?)

答案 2 :(得分:1)

问题在于operator< std::less<>operator<的定义。

使用当前的const,您实际上是在告诉编译器操作符可能会更改其任一操作数(因为操作符及其参数都未声明为std::less<>)。 由于operator<不希望更改operator<的操作数,因此您的实现是不可接受的。

要解决此问题,请将16 bool operator<( const A &a ) const 17 { 18 return m_value < a.m_value; 19 } 的定义更改为:

const

(注意在第16行添加operator<)。这告诉编译器你的std::less<>不会改变它的任何一个操作数,使{{1}}可以使用它。