问题标签 [generic-lambda]

For questions regarding programming in ECMAScript (JavaScript/JS) and its various dialects/implementations (excluding ActionScript). Note JavaScript is NOT the same as Java! Please include all relevant tags on your question; e.g., [node.js], [jquery], [json], [reactjs], [angular], [ember.js], [vue.js], [typescript], [svelte], etc.

0 投票
0 回答
64 浏览

c++ - 英特尔 icc 中通用 lambda 中的名称查找

如果在周围范围内导入来自不同命名空间的名称,则通用 lambda 中的名称查找规则是什么?

上述情况在gcc和 intel中给出了不同的结果icc。虽然gcc它编译时没有错误和警告,但icc 我收到错误消息

在第 (4) 行。另见https://godbolt.org/g/PYzWtw如果 (1) 被删除,或者如果在 (3)ns中再次导入命名空间中的名称,或者如果在 (2) 和 (4)auto中被替换为int. 因此,看似无关紧要的小改动会使代码编译为icc. 在所有情况下,它都可以与gcc.

这是英特尔编译器中的错误吗?

我的编译器设置:gcc 6.3.0,intel icc 18.0.1。还有clang 4它编译得很好。

由于它适用于非泛型 lambda,因此我认为问题与 lambda 的实例化点有关operator()。但我不知道哪个编译器正确执行。

0 投票
1 回答
889 浏览

c++ - 不能在命名空间中使用通用 lambda?

考虑以下代码

GCC 和 clang 都接受此代码,但 MSVC(测试版本 19.00.23506)给出:

error C2888: 'auto <lambda_ce48e25aa4b9e3d225584044e4eae9e2>::operator ()(_T1) const': symbol cannot be defined within namespace 'A'

事实上,如果我删除命名空间 A 并在全局命名空间中定义所有内容,代码就会被接受。如果我将 lambda 表达式设为非泛型,则相同。

有人可以解释 MSVC 在这段代码中看到的问题是什么吗?C++ 标准是否限制在上述上下文中使用泛型 lambda?

0 投票
2 回答
1117 浏览

c++ - 显式指定通用 lambda 的 operator() 模板参数是否合法?

是否符合以下 C++ 代码标准?

clang++ 3.8.0g++ 7.2.0可以很好地编译这段代码(编译器标志是-std=c++14 -Wall -Wextra -Werror -pedantic-errors)。

0 投票
2 回答
1527 浏览

c++ - 参数列表中带有省略号的 C++ Lambda

我正在开发一个使用 lambdas 来描述表达式术语范围的库。因为库必须分发唯一的整数来标识每个变量,所以如果库而不是用户构造变量并且用户代码将它们作为 lambda 参数接收是理想的。

(换句话说,我正在从 miniKanren 实现“call\fresh”的 C++ 模拟。)

由于用户可能希望在特定范围内引入从零到许多新变量的任何数字,我希望用户能够将具有不同数量参数的 lambdas 传递给库。但是,我不知道有任何(简单)方法(在 C++14 中)来推断任意 lambda 对象的参数数量。

我突然想到为什么不将固定数量(比如 10)的可变 id 参数传递给 lambda,并让用户代码在 lambda 中使用省略号来忽略不需要的参数?像这样的东西:

编译器资源管理器似乎接受 lambda 参数列表中的省略号,至少在 gcc 中是这样。

它会被称为这样的东西(注意代码总是传递 10 个变量 id,无论“f”是否只命名一个、两个或一个都不命名):

诚然这是一个令我感到惊讶的功能,有什么理由不使用带有省略号的 lambdas 吗?

0 投票
1 回答
580 浏览

c++ - 将转发 lambda 转换为函数指针

这里有两件事有效。我们可以实例化一个转发函数模板来获取一个带左值的函数指针:

我们还可以将采用左值的非捕获通用 lambda 转换为采用左值的函数指针:

但显然 GCC 和 Clang 都不会将转发通用 lambda 转换为采用左值的函数指针:

GCC 输出:

叮当输出:

尽管可以从转发 lambda 中获取采用左值的成员函数指针,但仍然如此:

...void (<lambda(auto:1&&)>::*)(int&) const按预期输出类型。

我认为引用折叠规则是任何模板实例化所固有的,并希望它能够工作。Clang 和 GCC 是否都有错误,或者标准实际上没有提供错误?

0 投票
3 回答
1053 浏览

lambda - 将 lambda 参数完美转发给成员函数,其中成员函数是非类型模板形参

语境

我想将一个成员函数和一个特定对象包装成一个函数对象(稍后我将用作回调)。我想为不同的成员函数和对象编写一次这个包装函数,特别是因为我的实际 lambda 在调用包装方法之前做了一些额外的工作。以下是一些可能的实现:

问题(简而言之)

我想要一个结合上述三个功能不同方面的功能:

  • 它应该将成员函数作为编译时模板参数,不像getCallbackPtr().
  • operator()不应该是模板函数,不像getCallbackTemplate().
  • 它的模板参数(成员函数指针除外)应该从函数使用中推断出来,不像getCallbackRedundant().

一些细节

以下是我希望成员函数成为模板参数的原因,尽管我必须承认这些在实践中可能不会产生明显的影响:

  • 优化器可能会直接调用成员函数,而不是通过函数指针。事实上,由于这是调用成员函数的唯一位置,它甚至可能被编译器内联到 lambda 中。
  • 生成的函数对象更小(一个指针而不是一个指针加一个成员函数指针),因此更可能适合std::function(小对象优化)的足迹。

以下是getCallbackTemplate()具有模板化的 的问题operator()

  • 它不适用于 Visual Studio。这对我来说是一个表演终结者。(错误是error C3533: a parameter cannot have a type that contains 'auto',参考template <auto memFn, class ClassT>。)
  • 如果传入了错误类型的参数,我怀疑它会比非模板化的编译器错误更复杂和令人困惑operator()(诚然,这只是一种预感)。
  • 模板operator()不能接受参数的初始化列表。这对我来说根本不是问题,但我提到它是为了记录。

我认为需要推断模板参数的原因相当清楚:getCallbackRedundant()冗长且难以使用。

这可以做到吗?如何?

0 投票
3 回答
213 浏览

c++17 - 使用任意数量的参数生成对 lambdas 的调用

以下定义已被证明对我非常有用:

基本上,折叠在逗号运算符上的参数包允许定义对接受参数的函数的多个调用。例如:

将在和1上调用匿名 lambda 。2"hello"

提出了这个想法,我想做同样的事情,但传递带有两个、三个等参数的 lambda。例如,类似的东西

任何可以实现它的线索、技术、想法等?

0 投票
3 回答
8511 浏览

c++ - 没有自动参数的 C++17 中的模板化 lambda

我有一个Derived继承自 class 的类Base<ResourceType>

我想创建一个创建类型对象的工厂Derived。我当然可以用函数来做到这一点:

但是,我无法为工厂编写 lambda 函数。如果我使用 auto 关键字接受模板参数,我可以编写模板化的 lambda 函数,但在这里我只想使用模板来确定返回类型。以下失败:

出现错误:

我只是错误地调用了 lambda 吗?还是我必须等待C++20

0 投票
2 回答
88 浏览

visual-studio - 具有两个相同类型的自动参数的 MSVC lambda

鉴于以下代码,Visual Studio 的行为似乎与 GCC 和 Clang 不同:

Clang 和 GCC 会接受这个,但是 MSVC 会抱怨这个消息

错误 C3536:“x”:在初始化之前无法使用

是否有一种解决方法可以强制 2 个参数类型相等?

注意:这个问题可以用 Visual Studio 2015、2017 和 Pre-2018 重现

在编译器资源管理器上查看此代码(您可以在不同的编译器之间切换)


编辑:

这段代码的行为并不是人们在阅读它时所期望的:只要 decltype(y) 可转换为 decltype(x),它就会编译,而不仅仅是当它们相等时。

所以,@nm 和@max66 的答案都是正确的:第一个是如果你想强制类型相等,第二个是如果你想使用 is_convertible。

我接受了第二个,因为它保留了原始代码行为(尽管原始代码可能是错误的:在我的情况下,类型相等的比较更好)

0 投票
1 回答
181 浏览

c++ - 为什么原始卷曲构造函数 {} 不返回右值?

假设您有一个带有 a 的可变参数类std::tuple,可以使用 args + 1 new arg 构造它。当使用std::apply()原始花括号构造函数构造时,该构造函数不返回右值。这意味着类不是移动构造的。下面举例说明。

输出是:

这个例子有点愚蠢,但说明了这一点。在第一个移动构造函数中,{}使用了元组复制构造。如果您使用硬编码取消注释第二个构造函数std::move(),则它可以工作。

我在最新的 VS、最新的 clang 和最新的 gcc 上进行测试。都有相同的结果。(魔杖盒: https ://wandbox.org/permlink/IQqqlLcmeyOzsJHC )

所以问题是,为什么不返回一个右值呢?我显然缺少 curly 构造函数的一些东西。这可能与可变参数无关,但我想我不妨展示一下真实场景。