在通用 lambda 中使用模板参数

2023-11-23

GCC允许使用以下语法作为扩展:

// a functional object that will add two like-type objects
auto add = [] <typename T> (T a, T b) { return a + b; };

In n3418在 2012 年关于泛型 lambda 的提案中,我们看到了允许上述内容的语法:

overload( []<class T>(T* p) {...},

然而,由于它是一个扩展,因此语法显然不存在(或不允许)。当我们有 auto 时,上面的内容在什么情况下有用,为什么语法不存在(或不允许)?


在我看来,C++14 的多态 lambda 更加简洁。

您可以重现示例情况的效果,如下所示:

struct A {};
struct B {};

int operator+(A, A) { return 1; }
int operator+(B, B) { return 2; }
int operator+(A, B) { return 3; }
int operator+(B, A) { return 4; }

int main() {
    auto add = [](auto a, decltype(a) b) { return a + b; };
    auto flexible_add = [](auto a, auto b) { return a + b; };

    add(A{}, A{});  // works
    add(B{}, B{});  // works
    add(A{}, B{});  // doesn't work

    flexible_add(A{}, A{});  // works
    flexible_add(B{}, B{});  // works
    flexible_add(A{}, B{});  // works

    auto deref = [](auto *a) { return *a; };
    int foo{};
    A a;
    B b;
    deref(&foo); // works
    deref(&a);   // works
    deref(&b);   // works
    deref(foo);  // doesn't work
    deref(a);    // doesn't work
    deref(b);    // doesn't work
}

尽管在很多情况下 GCC 扩展功能更强大,而不仅仅是在您的用例上(它更自然地适合)。例如,关于非类型模板参数:

#include <cstddef>
#include <utility>
#include <iostream>

void print(std::initializer_list<std::size_t> il)
{
    for (auto&& elem : il) std::cout << elem << std::endl;
}

int main()
{
    auto indexed_lambda = [] <std::size_t... Is> (std::index_sequence<Is...>) { print({Is...}); };

    indexed_lambda(std::make_index_sequence<5>{});    
}

Coliru

复杂的泛型参数类型:

void foo() {}

int main() {
    auto accept_no_args_fun_only = [] <typename R> (R (*)()) {};

    accept_no_args_fun_only(foo);
}

Coliru

变量:

#include <tuple>
#include <vector>

int main() {
    auto accept_vector = [] (std::vector<auto> &&) {}; // Unconstrained placeholder from Concept TS, but not variadic
    auto accept_tuple = [] <typename... Args> (std::tuple<Args...> &&) {};

    accept_vector(std::vector{42});
    accept_tuple(std::tuple{42});
}

Coliru

我不知道涉及包含通用 lambda 表达式的讨论,但我可以看到有人在思考,当当前语法涵盖了大多数用例时,是否值得包含这样的扩展,它很简洁,并且适合 lambda 表达式的意图,而 lambda 最常见的是用于生成简短的代码片段。

EDIT

GCC 扩展已决定成为 C++ 的一部分首届 C++20 ISO 标准会议:

  • http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2017/p0428r1.pdf
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

在通用 lambda 中使用模板参数 的相关文章

随机推荐

  • 相同美学的多个传说

    我正在尝试使用facet grid or facet wrap和这个结合geom raster 然而 在每个面板中 z审美是不同尺度的 例如 Data at end of question ggplot dd aes x y geom ra
  • 没有可以捕获托管变量的 lambda 的解决方法

    在 C CLI 中 您无法创建托管 lambda 就像在 C 中一样 因此无法捕获托管变量 您可以创建常规方法 而不是 lambda 但您仍然无法捕获托管变量 C CLI 代码中是否有可采用的标准解决方法 换句话说 我正在寻找一个可以在 C
  • 如何在 symfony2 中禁用数据库配置

    我正在开发的新应用程序正在使用 Symfony2 没有可供使用的数据库连接 相反 它是建立在许多 Web 服务调用之上的 在 Symfony app config 下 我想删除所有 database 条目 但是当我这样做时 我得到一个 Pa
  • 如何在 elastic beanstalk 中扩展 nginx 配置 (Amazon Linux 2)

    我听从了建议here配置 nginx 反向代理以允许大于默认 1mb 的文件 所以 我的代码在 platform nginx conf d prod conf看起来像这样 http client max body size 30M 然而 这
  • 适用于 iPhone 的 UIPOPOVER?或者是假的?

    谁能看一下这个吗 http www woowoomac com storage awesome note iphone note todo app menus jpg SQUARESPACE CACHEVERSION 12685817624
  • 如何让 CRON 调用正确的路径

    我试图让 cron 调用正确的路径 当我从 shell 运行 Python 脚本时 脚本运行良好 因为它使用 bashrc 中设置的 PATH 但是当我使用 cron 时 所有 PATH 都不会从 bashrc 使用 是否有一个文件可以像
  • WCF 4 服务的扁平 WSDL

    使用 WCF 3 5 和来自 Christian Weyer 的 FlatWsdl EndpointBehavior 我能够为我的 WCF 服务获取单个平面 WSDL 文件 而无需任何
  • DDD-- 如何补充水分

    Question 从存储库中重新水化聚合体的最佳 高效且面向未来的方法是什么 所提供的方法有哪些优点和缺点 我的看法是否正确 假设我们有一个带有私有 setter 和公共 getter 的聚合根用于访问state 行为是通过聚合根上的方法完
  • Dynamic_cast 中的类型必须是完整类类型的指针或引用,或者 void *

    我希望有人能理解为什么下面的代码失败 我试图从 osg Node 节点对象获取 PositionAttitudeTransform Openscenegraph 类 的实例 但下面有粗体的编译器错误 void CameraPosCallba
  • 为什么扩展元素不适合复制多维数组?

    来自MDN 传播语法 注意 通常 ES2015 中的扩展运算符在复制数组时会深入一层 因此 它们不适合复制多维数组 这与 Object assign 和对象扩展语法的情况相同 请参阅下面的示例以更好地理解 var a 1 2 3 var b
  • Codeigniter 如何创建 PDF

    我要创建一个发票系统 我现在正在为此做准备 我将使用 Codeigniter 问题是我想创建 PDF 格式的发票 这样我就可以通过电子邮件发送它 你们有什么建议 我正在考虑 HTML 到 PDF 的转换 或者在屏幕上显示发票并安装 pdf
  • Boost 随机和 OpenMP

    我从 OpenMP 并行代码部分收到 总线错误 我在下面重新创建了我的问题的简单版本 该代码本质上对函数进行了多次调用uniform distribution 它使用 Boost 的uniform int distribution 绘制 0
  • SQL Server 2005 - 将列设置为只读

    我在 SQL Server 2005 数据库的表中有一个 InsertTime 字段 当记录首次插入数据库时 该字段默认为 getDate 我想确保此专栏不再更新 是否可以将此列设置为只读 或者是否有更好的方法来执行此操作 而无需为开发人员
  • 使用 Java 的 Google 数据存储模拟器(不使用 GAE)

    我正在使用 Google Cloud 的 Java 数据存储客户端库来访问 Cloud Datastore Note 我没有使用 App Engine 来部署我的应用程序 只是出于开发目的运行本地应用程序 按照示例 我可以读取 写入云数据存
  • 将模板成员函数的专门化定义(没有默认主体)放在源文件中是否安全?

    这就是我的意思 test h class cls public template lt typename T gt void f T t test cpp template lt gt void cls f const char main
  • 关于不使用 Interface Builder 进行 iPhone GUI 设计的教程?

    有谁知道有关仅使用代码而不是 Interface Builder 进行 iPhone GUI 设计的好教程吗 我是 iPhone 开发新手 我想更好地了解幕后发生的事情 查看 SDK 中的 UI 目录示例 它展示了以多种方式使用的所有单独控
  • 我可以在不安装的情况下使用git吗?

    我听说过有关 git 的好消息 我想在安装它之前尝试一下 如果我想在学校使用 git 那么将它放在闪存驱动器上也很棒 是否可以使用完整路径 例如 path to git init 我主要使用 Mac OS X 所以问题主要针对 Mac 但我
  • Symfony/Doctrine:DateTime 作为主键

    我正在尝试使用日期作为主键创建一个实体 问题是 Symfony 无法将我正在使用的 DateTime 转换为字符串以将其引入到 IdentityMap 中 在实体持久化期间出现以下错误 Catchable Fatal Error Objec
  • PHP 运算符优先级和字符串连接?

    请看下面的代码片段 i 1 echo i i 很快 我以为结果会是12但实际结果是21 also echo i i 我以为会是12但它的11 echo i i result is 1 echo i i 1 result is 2 But w
  • 在通用 lambda 中使用模板参数

    GCC允许使用以下语法作为扩展 a functional object that will add two like type objects auto add