0

如何在包含类的向量中使用 std::less,所有谷歌结果都带有纯 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 >

似乎 less 需要一个仿函数operator()(),如何避免这种情况?我需要实现 operator<( 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]
4

3 回答 3

2

实现一个operator<for 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- 这是第一个参数(考虑左侧),您还可以绑定到第二个参数(右侧 - using 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)
于 2012-11-23T13:25:14.670 回答
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;
    }
};

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

于 2012-11-23T13:36:43.143 回答
2

问题在于您对引擎盖下使用operator<的定义。std::less<>

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

要修复它,请将定义更改operator<为:

16       bool operator<( const A &a ) const
17       {
18          return m_value < a.m_value;
19       }

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

于 2012-11-23T13:56:14.047 回答