【问题标题】:Can 'auto' be used as a subtype of lambda argument in C++?'auto' 可以用作 C++ 中 lambda 参数的子类型吗?
【发布时间】:2021-07-17 08:41:12
【问题描述】:

GCC 接受带有 auto 作为 lambda 参数类型一部分的 C++ 代码,例如:

#include <vector>
#include <iostream>

int main()
{
    auto make_vector = []( std::initializer_list<auto> v ) 
        { return std::vector<typename decltype(v)::value_type>{v}; };
    auto v = make_vector( {1,2} );
    std::cout << v[0] << ' ' << v[1] << '\n';
}

https://gcc.godbolt.org/z/z43bEjMc9

这里的参数类型是std::initializer_list&lt;auto&gt;,有时候真的很方便。但其他编译器抱怨:

模板参数不能是包含'auto'的类型

它是语言的仅 GCC 扩展,还是将出现在其他编译器中的新 C++ 功能?如果是第一种情况,那么如何关闭它以最大化语言一致性?

【问题讨论】:

    标签: c++ lambda


    【解决方案1】:

    看起来是bug in GCC。尽管它说它已在您使用的 GCC 版本中解决...

    您可以阅读here 详细了解为什么在这种情况下不能使用auto

    有人正确地向我指出,这种情况是针对函数参数的。在 C++20 中仍然不允许,请参阅 this answer

    【讨论】:

    • 在最新版本的 gcc 中不允许使用 A&lt;auto&gt; a 形式的变量声明。函数参数不同。
    • @n.1.8e9-where's-my-sharem。好点,但我已经查过了,但它仍然相关。我会更新我的答案。
    • 我也查了,看来毕竟是个bug。
    • @n.1.8e9-where's-my-sharem。我似乎找不到 GCC 的错误报告。有没有偶然发现的?
    【解决方案2】:

    这不是声明通用 lambdas 的有效方式。 [dcl.spec.auto.general]/2:

    一个 placeholder-type-specifier 形式为 type-constraintopt auto 可以用作函数声明的 parameter-declarationdecl-specifier-seqdecl-specifier 或 lambda-expression 并且,如果不是 auto type-specifier 引入 trailing-return-type(见下文),则为函数声明的通用参数类型占位符lambda-expression

    注意std::initializer_list&lt;auto&gt;不是type-constraintoptauto的形式。

    从 C++20 开始,您可以为 generic lambdas 删除 模板参数列表。例如

    auto make_vector = []<typename T>( std::initializer_list<T> v ) 
        { return std::vector<typename decltype(v)::value_type>{v}; };
    

    【讨论】:

      猜你喜欢
      • 2018-02-12
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-08-26
      相关资源
      最近更新 更多