c++函数对象疑问

在家等待开工,看了本c++入门书,在看一篇文章中有介绍函数对象,自己搜了下,但是不清楚这种写法是什么意思:

template <class T>
struct less
  : binary_function<T, T, bool> {
  bool operator()(const T& x,
                  const T& y) const
  {
    return x < y;
  }
};

这种写法中的binary_function<T, T, bool>是啥意思?

常见的函数对象写法:

class increment
{
private:
    int num;
public:
    increment(int n) : num(n) { }
    int operator () (int arr_num) const {
        return num + arr_num;
    }
};

我理解的函数对象用法是:

increment(10);

//等价于
increment.operator()(10);

另外一个例子中也存在疑问:


#include <complex>        // std::complex
#include <iostream>       // std::cout/endl
#include <unordered_map>  // std::unordered_map
#include <unordered_set>  // std::unordered_set

using namespace std;

namespace std {

template <typename T>
struct hash<complex<T>> {
  size_t
  operator()(const complex<T>& v) const
    noexcept
  {
    hash<T> h;
    cout << "Hello,world"<<endl;
    return h(v.real()) + h(v.imag());
  }
};

}  // namespace std

int main()
{
  unordered_set<int> s{
    1, 1, 2, 3, 5, 8, 13, 21
  };

  unordered_map<complex<double>,
                double>
    umc{{{1.0, 1.0}, 1.4142},
        {{3.0, 4.0}, 5.0}};
  return 0;
}

这里我在hash中添加了打印,结果打印了三次hello,world.
但是Unorder_map中只有两个元素,讲道理两个元素插入,计算hash也是计算两次呀,为什么打印三次呢?

回复
阅读 1.5k
2 个回答

std::binary_function 是一个二元函数对象的模板类。可以用作二元函数对象的基类。

不过再 C++17 里已经把这个给删了,所以最后不要再用这个了,直接写函数对象就好了。

但是Unorder_map中只有两个元素,讲道理两个元素插入,计算hash也是计算两次呀,为什么打印三次呢?

C++ 本身并没有要求算几次。

这个算几次是要看算法实现的,不同的算法计算的次数不一定一样的。想知道细节,只能取看代码了。

stdlibc++ 里,每出现一个新的桶(没有 rehash 的时候)(除了第一元素),内部数据结构会有调整,需要多计算一个(已存在元素的)hash。

首先,得声明一句,此类在 C + + 11中已被弃用。
这是标准二进制函数对象的基类。
通常,函数对象是定义了成员函数运算符()的类的实例。此成员函数允许对象使用与常规函数调用相同的语法,因此当需要泛型函数类型时,可以将其类型用作模板参数。
对于二进制函数对象,这个运算符()成员函数接受两个参数。
Bin _ function 只是一个基类,从中派生特定的二进制函数对象。它没有定义操作符()成员(这是派生类需要定义的)——它只有三个公共数据成员,它们是模板参数的 typedef。

也许说了这么多,过于复杂,难懂,因此我这里直接举一个demo,更能理解:

// binary_function example
#include <iostream>     // std::cout, std::cin
#include <functional>   // std::binary_function

struct Compare : public std::binary_function<int,int,bool> {
  bool operator() (int a, int b) {return (a==b);}
};

int main () {
  Compare Compare_object;
  Compare::first_argument_type input1;
  Compare::second_argument_type input2;
  Compare::result_type result;

  std::cout << "Please enter first number: ";
  std::cin >> input1;
  std::cout << "Please enter second number: ";
  std::cin >> input2;

  result = Compare_object (input1,input2);

  std::cout << "Numbers " << input1 << " and " << input2;
  if (result)
      std::cout << " are equal.\n";
  else
      std::cout << " are not equal.\n";

  return 0;
}

输出试试你就知道了,哈哈哈

已参与了 SegmentFault 思否社区 10 周年「问答」打卡 ,欢迎正在阅读的你也加入。

推荐问题
宣传栏