• std::apply 源码分析


    std::apply 源码分析

    背景:

    std::apply 适合感觉跟std::invoke 有点相似, 前边参数是可以调用的对象, 后边是一个tuple类型,在做线程的任务包装的时候,可以使用这个apply,

    接下来我们就看下它的源码

    std::apply 用例

    C++
    #include
    #include
    #include <utility>
     
    int add(int first, int second) { return first + second; }
     
    template
    T add_generic(T first, T second) { return first + second; }
     
    auto add_lambda = [](auto first, auto second) { return first + second; };
     
    template
    std::ostream& operator<<(std::ostream& os, std::tuple const& theTuple)
    {
        std::apply
        (
            [&os](Ts const&... tupleArgs)
            {
                os << '[';
                std::size_t n{0};
                ((os << tupleArgs << (++n != sizeof...(Ts) ? ", " : "")), ...);
                os << ']';
            }, theTuple
        );
        return os;
    }
     
    int main()
    {
        // OK
        std::cout << std::apply(add, std::pair(1, 2)) << '\n';
     
        // Error: can't deduce the function type
        // std::cout << std::apply(add_generic, std::make_pair(2.0f, 3.0f)) << '\n';
     
        // OK
        std::cout << std::apply(add_lambda, std::pair(2.0f, 3.0f)) << '\n';
     
        // advanced example
        std::tuple myTuple{25, "Hello", 9.31f, 'c'};
        std::cout << myTuple << '\n';
    }

    https://en.cppreference.com/w/cpp/utility/apply

    Output

    C++
    3
    5
    [25, Hello, 9.31, c]

    std::apply 源码

    C++
    template
    inline _LIBCPP_INLINE_VISIBILITY
    constexpr decltype(auto) apply(_Fn && __f, _Tuple && __t)
    _LIBCPP_NOEXCEPT_RETURN(
        _VSTD::__apply_tuple_impl(
            _VSTD::forward<_Fn>(__f), _VSTD::forward<_Tuple>(__t),
            typename __make_tuple_indices>>::type{})
    )

    这个跟std::make_from_tuple基本上一样,请移步到https://blog.csdn.net/c553110519/article/details/126838742

    汇编

    C++
    int TestApply(int a, int b)
    {
        return a + b;
    }
    void Test()
    {
       int sum = std::apply(TestApply, std::tuple(1,2));
        std::cout< }

    Assembly language
        0x1000036f0 <+0>:   sub    sp, sp, #0x30
        0x1000036f4 <+4>:   stp    x20, x19, [sp, #0x10]
        0x1000036f8 <+8>:   stp    x29, x30, [sp, #0x20]
        0x1000036fc <+12>:  add    x29, sp, #0x20
        0x100003700 <+16>:  nop   
        0x100003704 <+20>:  ldr    x0, #0x93c                ; (void *)0x00000001fd11dd98: std::__1::cout
        0x100003708 <+24>:  mov    w1, #0x3
        0x10000370c <+28>:  bl     0x100003c94               ; symbol stub for: std::__1::basic_ostream >::operator<<(int)
     

    可以看的出来最终转成sum = std::apply(TestApply, std::tuple(1,2));汇编后mov    w1, #0x3,编译器把中间过程给做了,丝毫没有影响到性能,constexpr的特性所致

  • 相关阅读:
    Android App开发超实用实例 | OpenCV在Android手机实现在图像上添加文本
    折磨人的算法题咋解?阿里内部强推超全Java算法学习指南,已被彻底征服,早知道可以少掉我多少头发了
    systemverilog 过程控制语句
    LVS DR模式
    [南京大学]-[软件分析]课程学习笔记(一)-introduction
    Nginx配置反向代理解决跨域问题
    微软研究院团队获得首届AI药物研发算法大赛总冠军
    C++:C++入门基础
    打字速度测试,生成您的打字速度证书?
    PHP8中伪变量“$this->”和操作符“::”的使用-PHP8知识详解
  • 原文地址:https://blog.csdn.net/c553110519/article/details/126840102