首页 > 编程语言 >C++ lambda 表达式与「函数对象」(functor)

C++ lambda 表达式与「函数对象」(functor)

时间:2024-11-17 16:56:39浏览次数:1  
标签:__ std int C++ sort functor lambda

C++ lambda 表达式与「函数对象」(functor)

  • Created: 2024-06-27T16:29+08:00
  • Published: 2024-11-17T17:01+08:00
  • Categories: C-CPP

functor(Function Object)

首先要介绍的是 functor——一个重载了 operator() 的类,该类的实例可以使用 operator()

What are C++ functors and their uses? - Stack Overflow

stackoverflow 上的例子很好,改一下放在这里:

struct add_x
{
    add_x(int val) : x(val) {} // Constructor
    int operator()(int y) const { return x + y; }

private:
    int x;
};

struct output {
    void operator()(const int & x) {
        std::cout << x << " ";
    }
};

int main()
{
    vector<int> x{0, 1, 2, 3};
    vector<int> y(x.size());
    // Now you can use it like this:
    add_x add_42(42);            // create an instance of the functor class
    int i = add_42(8);           // and "call" it
    std::cout << i << std::endl; // 50

    // Pass a functor to std::transform, which calls the functor on every element
    // in the input sequence, and stores the result to the output sequence
    std::transform(x.begin(), x.end(), y.begin(), add_42); // y[i] = x[i] + 42
    std::for_each(x.begin(), x.end(), output());

    for (auto &i : y)
    {
        std::cout << i << " ";
    }
    return 0;
}

观察下 std::for_each() 这类函数的函数签名,最终只是调用了传入参数的 () 运算符,所以可以传入一个 functor。

代码见 ./use-functor-lambda-to-sort.cpp

template <typename _InputIterator, typename _Function>
_GLIBCXX20_CONSTEXPR
    _Function
    for_each(_InputIterator __first, _InputIterator __last, _Function __f)
{
    // concept requirements
    __glibcxx_function_requires(_InputIteratorConcept<_InputIterator>)
        __glibcxx_requires_valid_range(__first, __last);
    for (; __first != __last; ++__first)
        __f(*__first);
    return __f; // N.B. [alg.foreach] says std::move(f) but it's redundant.
}

只是简单地将传入参数 _f 作用于 element,对于 std::sort(),其函数签名为 sort(_RandomAccessIterator __first, _RandomAccessIterator __last, _Compare __comp),也只是简单地使用 __comp()。所以只要传入的对象支持 () 运算就可以。

lambda

C++ 中 Lambda 表达式(匿名函数)与传统的函数指针有什么本质区别? - 雨乐的回答 - 知乎

lambda 实际上代码生成出了一个 functor,而 capture list 中的参数就是 functor 中的成员变量。
默认引用捕获的成员变量是只读的,可以使用 mutable 来改变。

可以参考 C++ Insights - Iterator tests 看中间代码。

bool less_function(int const &a, int const &b)
{
    return a < b;
}

struct Less
{
    bool operator()(int const &a, int const &b) const
    {
        return a < b;
    }
};

auto less_lambda = [](int const &a, int const &b)
{
    return a < b;
};

Less less_functor{}; // an instance of less

int main()
{
    vector<int> v = {1, 3, 5, 7, 2, 4, 6};

    std::sort(v.begin(), v.end(), less_lambda);
    std::sort(v.begin(), v.end(), less_function);
    std::sort(v.begin(), v.end(), less_functor);

    for (auto &i : v)
    {
        std::cout << i << " ";
    }
    std::cout << std::endl;
    return 0;
}

面试问题

使用 lambda 实现函数对象

让介绍一下 C++ 里的 lambda。给了 struct A {int x;}; std::vector<A> v;,让用 std::sort 来排序:std::sort(v.begin(), v.end(), [](A &a, A &b) {return a.x < b.x;});
指出 lambda 是一种语法糖,要我把它用函数对象实现。我当时不太会函数对象。
问了这里第三个参数 [](A &a, A &b) {return a.x < b.x;} 是什么类型。问了 std::sort 的函数签名是什么。当时不会。参见 理解 STL —— 迭代器与函数对象。

——咸鱼暄的代码空间

代码见 ./use-functor-lambda-to-sort.cpp

标签:__,std,int,C++,sort,functor,lambda
From: https://www.cnblogs.com/dutrmp19/p/18550751

相关文章

  • C++ 模板
    C++模板Created:2024-03-24T20:24+08:00Published:2024-11-17T16:37+08:00Categories:CPP目录偏特化类模板函数模板形参包Question我记不住模板的语法,尤其是偏特化的语法,怎么办?面试问题利用类模板和函数模板实现编译器计算斐波那契数列模板的声明和定义为什么不能分开写......
  • c++入门基础后续
    1.缺省参数缺省参数是指在声明或定义的同时给上指定的一个缺省值,在调用函数是如果没有传指定的实参那么就会用这个缺省值。缺省参数分为全缺省和半缺省。全缺省就是全部形参给缺省值,半缺省就是部分形参给缺省值。C++规定半缺省参数必须从右往左依次连续缺省,不能间隔跳跃......
  • C++仍要用的scanf函数介绍
    很多C++初学者刚学便是使用cin和cout,这无可厚非;但C语言中的scanf函数在一些特定情况下仍必不可少,故写给C++初学=者scanf函数的部分介绍以及具体使用情景。scanf输入数字的用法头文件:#include<cstdio> 调用格式:scanf(格式控制字符串,变量地址列表);注:格式说明和各输入......
  • CSP/信奥赛C++语法基础刷题训练(11):洛谷P5743:猴子吃桃
    CSP/信奥赛C++语法基础刷题训练(11):洛谷P5743:猴子吃桃题目描述一只小猴买了若干个桃子。第一天他刚好吃了这些桃子的一半,又贪嘴多吃了一个;接下来的每一天它都会吃剩余的桃子的一半外加一个。第n......
  • CSP/信奥赛C++语法基础刷题训练(12):洛谷P1047:[NOIP2005 普及组] 校门外的树
    CSP/信奥赛C++语法基础刷题训练(12):洛谷P1047:[NOIP2005普及组]校门外的树题目描述某校大门外长度为lll的马路上有一排树,每两棵相邻的树之间的间隔都是......
  • 【华为OD技术面试手撕真题】84、前 K 个高频元素 | 手撕真题+思路参考+代码解析(C & C+
    文章目录一、题目......
  • C++因子个数
    目录1.题目描述2.输入输出3.样例输入 Copy样例输出 Copy1.题目描述一个自然数N的正因子个数记为F(N),例如18的所有正因子为1、2、3、6、9、18,所以F(18)=6。现在给出K,求所有满足F(N)=K的N中最小的数。2.输入从文件读入数据,第一行为K,其中0<K≤80。输出......
  • 【C++】引用
    目录引用的概念引用的特点引用定义时必须初始化引用的类型必须与被引用对象的类型相同一个变量可以设置多个引用引用只能对应一个实体引用有传递性赋值与引用的区别引用作参数引用作参数-利用引用的变量共同指向同一块内存空间交换两个变量传递单链表节点指针引......
  • GESP2023年12月认证C++四级( 第一部分选择题(11-15))
    ......
  • GESP2023年12月认证C++四级( 第二部分判断题(1-5))
    ......