模板lambda vs foundor带有模板操作员()
template lambda vs functor with template operator()
受这个问题的启发,我想将c++20
模板lambda与具有模板operator()
的函数进行比较。
作为测试用例,请考虑将模板lambda作为参数的模板函数call
,并将此lambda称为使用某些模板参数对其进行实例化。以下c++20
代码例证了这个想法。
#include <tuple>
#include <utility>
template <int I, class Lambda, class... ArgsType>
void call(Lambda&& F, ArgsType&& ...args)
{
F.template operator()<I>(std::forward<ArgsType>(args)...);
}
int main() {
std::tuple<int, double, int> t{0,0,0};
int a = 2;
auto f = [&]<int I>(auto& x) { std::get<I>(x) += I + a; };
call<0>(f, t);
return 0;
}
在c++11
/c++14
/c++17
中,没有模板lambda,可以使用函数,具有模板operator()
,如以下代码。
#include <tuple>
#include <utility>
template <int I, class Lambda, class... ArgsType>
void call(Lambda&& F, ArgsType&& ...args)
{
F.template operator()<I>(std::forward<ArgsType>(args)...);
}
struct Functor {
template <int I, class T>
void operator()(const int& a, T& x) { std::get<I>(x) += I + a; };
};
int main() {
std::tuple<int, double, int> t{0,0,0};
int a = 2;
Functor func{};
call<0>(func, a, t);
}
我在第二个示例中看到的主要缺点是,要模拟lambda捕获,需要将所有局部变量(在这种情况下为 int a
(明确传递给函数。如果Functor::operator()
需要其"所有者"的许多变量,这可能很乏味。最终,也许也可以将指针this
传递给Functor::operator()
。c++20
中没有这种并发症,其中lambda捕获会照顾捕获所需的变量。
除了简单之外,上面概述的两种方法之间还有其他具体差异吗?效率呢?
我在第二个示例中看到的主要缺点是,要模仿lambda捕获,需要明确将所有局部变量(在本例中为int a(转移到函数。
我不同意。
您几乎可以将lambda视为具有operator()
的类/结构,而某些对应于捕获变量的成员。
所以而不是
[&]<int I>(auto& x) { std::get<I>(x) += I + a; };
您可以写(已经来自C 11(
struct nal // not a lambda
{
int const & a;
template <int I, typename T>
auto operator() (T & x) const
{ std::get<I>(x) += I + a; }
};
并按照以下方式使用它
call<0>(nal{a}, t);
我在函数上看到的主要缺点(我想这是一个不利的问题(是,您不能简单地通过参考或值捕获([&]
或[=]
(,所有外部变量,但您必须明确列出您使用的所有变量,包括定义函子和初始化函数对象。
主题:观察我已经在我的nal
结构中标记了const
operator()
。
如果您不修改捕获的变量,则lambdas等于具有常数operator()
的函子。
如果您将函数作为常量参考
传递,这很重要template <int I, class Lambda, class... ArgsType>
void call (Lambda const & F, ArgsType&& ...args)
{ // ......^^^^^^^^^^^^^^ now F is a constant reference
F.template operator()<I>(std::forward<ArgsType>(args)...); // compilation error
// if operator()
// isn't const
}
如果operator()
不是const
- lambda参数转换为constexpr技巧,然后获取带链接的数组
- 可组合的lambda/std::函数与std::可选
- C++Boost Asio Pool线程,带有lambda函数和传递引用变量
- 如何建立使用模板函数的lambda函数的尾部返回类型
- 如何将lambda作为模板类的成员函数参数
- C++从其他 constexpr 创建 lambda 不能按顺序执行 Constexpr
- 在 lambda 捕获中声明的变量的类型推导
- <<操作员在下面的行中工作
- 我可以将调用类的"this"传递给 lambda 函数吗?
- 为什么lambda在clang上崩溃而不是在gcc上崩溃
- 模板函数指针和lambda
- 两组使用lambda函数的大括号
- 使lambda不可复制/不可移动
- FLTK:按下哪个按钮 - 将数字传递给按钮的回调 (lambda)
- 尝试将lambda函数放在队列中时出现一般分配器错误(可能是与unique_ptr有关的错误)
- 将带有unique_ptr的可变 lambda 传递给 const&std::function
- AWS Lambda C++运行时权限被拒绝
- 捕获lambda中的std::数组
- 这 4 个 lambda 表达式之间有什么区别?
- 模板lambda vs foundor带有模板操作员()