今天,我偶然发现了以下代码片段:
#include <utility>
int main()
{
auto a = [](std::pair<auto, auto> value)
{
};
a(std::pair<int, bool>{ 3, true });
}
我只有一个问题:标准支持这段代码吗?
它在 GCC 中编译(使用 -std=c++14
),但不是 clang 或 Visual Studio 2015 (VC++14)。
这似乎应该成为标准的一部分,因为如果 lambda 应该具有与常规函数相同的模板支持,那么应该支持它。
这似乎可以转换为所有模板类型,而不仅仅是 std::pair
。
最佳答案
在 C++14 中,模板参数中不允许 auto
,无论是否在 lambda 中。 Clang 和 Visual Studio 都有权拒绝此代码。
C++14 标准引用是 [dcl.spec.auto]。在以下上下文中允许使用 auto
说明符:
- 在函数声明符的 decl-specifier-seq 中(例如,
auto f();
)(第 2 段)< - 在conversion-function-id(即类中的
operator auto()
)(第2段) - 在函数声明符的 trailing-return-type 中(例如,
auto f() -> auto;
)(第 2 段) - 在 lambda 的参数声明(作为声明说明符之一)的声明说明符序列中(段落3); -这就是允许通用 lambda 存在的原因-
- 在 block 作用域或命名空间作用域的变量声明中(第 4 段)
- 在 for 循环控制变量的声明中(第 4 段),包括基于范围的 for 循环(第 5 段)
- 在
if
或switch
语句或循环的条件下(第 5 段) - 在
new
表达式中,即new auto(42)
(第 5 段) - 在类定义中静态数据成员的声明中(第 5 段)
最后,
A program that uses
auto
ordecltype(auto)
in a context not explicitly allowed in this section is ill-formed.
因此,auto
不允许出现在模板参数中,因为 [dcl.spec.auto] 中未列举这种情况。
我不知道为什么 gcc 允许它。它可能与 Concepts Lite 有关,但我不知道 Concepts Lite 是否真的允许这种用法。它可能只是一个易于实现的无关扩展。我假设
[](std::pair<auto, auto> value) { /* ... */ }
翻译成
struct __some_unique_name {
template <typename T1, typename T2>
auto operator()(std::pair<T1, T2> value) const { /* ... */ }
// ...
};
关于c++ - lambdas 中的模板参数列表中的 auto 是标准的一部分吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32322255/