使用 `std::apply` 迭代 `std::tuple`

问题描述 投票:0回答:1

我尝试使用

std::apply
调用元组所有元素中的特定成员函数。当我使用 lambda 时这有效,但在定义自由函数时则无效。

以下模板元组 - 在每个元素上调用函数以下代码在使用 lambda 时有效:

#include<tuple>
#include<iostream>

struct Double  {
     void print() { std::cout << "Double!" << std::endl;}
};

struct Vector  {
    void print() { std::cout << "Vector!" << std::endl;}
};

template<class ...T>
void printAll2(T &...x){(x.print(), ...);}

int main() {

    auto workspace = std::make_tuple<Vector, Double, Vector>({},{},{});
    auto printAll = [](auto &...x){(x.print(), ...);};

    std::apply(printAll , workspace);

    // This does not work.
    //std::apply(printAll2, workspace);

    return 0;
}

但是,当我尝试使用免费功能时

printAll2
我收到错误:

<source>:22:5: error: no matching function for call to 'apply'
   22 |     std::apply(printAll2, workspace);
      |     ^~~~~~~~~~
/opt/compiler-explorer/gcc-snapshot/lib/gcc/x86_64-linux-gnu/15.0.0/../../../../include/c++/15.0.0/    tuple:2955:5: note: candidate template ignored: couldn't infer template argument '_Fn'
 2955 |     apply(_Fn&& __f, _Tuple&& __t)
      |     ^
1 error generated.
Compiler returned: 1

lambda 和函数有什么区别?

非常感谢!

c++ templates tuples c++20 variadic-functions
1个回答
0
投票

printAll
printAll2
的区别:

printAll2
不是函数,而是函数模板。

当您将特定函数与特定参数一起使用时,编译器会根据该函数实例化特定函数。但它本身并不具体,也不是你可以做到的

apply

为了应用它,您必须指定模板参数,从而使其成为一个具体函数:

//-------------------vvvvvvvvvvvvvvvvvvvvvv--------------
std::apply(printAll2<Vector, Double, Vector>, workspace);
另一方面,

printAll
是一个通用的 lambda。
因此,它是一个未命名的 concerete 类的实例,其中只有
operator()
是模板化的。
调用 lambda 时,lambda 的通用性质就会生效。此时,编译器会使用相关参数实例化特定的
operator()

在内部,此类是按照此示例的方式实现的:

class __some_internal_class_name__ {
public:
    template<class ...T>
    void operator()(T &...x) const {(x.print(), ...);}
};

由于

printAll
是该类的具体对象,因此可以将其传递给
std::apply

© www.soinside.com 2019 - 2024. All rights reserved.