【问题标题】:Why are C++20 template lambdas using typename keyword?为什么 C++20 模板 lambda 使用 typename 关键字?
【发布时间】:2019-06-07 09:46:22
【问题描述】:

我理解一致性参数,但模板的大多数参数都是类型,所以我觉得既然 lambdas 是定义结构的简洁方式,它可能应该默认为typename/class(你仍然需要写int/size_t/short)。

如果有人不熟悉 C++20 中 lambdas 的变化,这里是示例:

[]<typename T>(const std::vector<T>& v)
{
    for(const auto& x : v) { std::cout << x; }
};

我的问题是为什么不:

[]<T>(const std::vector<T>& v)
{
    for(const auto& x : v) { std::cout << x; }
};

【问题讨论】:

  • [](const std::vector&lt;auto&gt; &amp;v) { }; 在 GCC9 中工作,但我不确定这是标准的。我认为 TS 的概念允许这样的语法。

标签: c++ typename c++20 generic-lambda


【解决方案1】:

问题是这个已经有意义了:

template <T> void foo();

这是一个函数模板,其中一个模板参数是一个非类型模板参数,其类型为T,并且该模板参数没有名称。

如果相同的语法意味着非常不同的东西,这将非常令人困惑,具体取决于您是引入函数模板还是通用 lambda——也就是说,两个非常相似的上下文服务于相似目的!

另外......如果你真的想要一个非类型模板参数,你会怎么做?就是不能拥有一个?

【讨论】:

  • 你能举出完整的例子:已经有意义吗?我不明白。我试过这个,但如果它是有效的 cpp godbolt.org/z/hghhjc,clang/gcc 不同意
  • @NoSenseEtAl 您需要在您的结构中添加一个 auto operator &lt;=&gt;(T const &amp;) = default; 才能使其工作,但这些编译器仍然不支持。
  • @NoSenseEtAl This 将是一个有效的 C++20 程序,只是尚未实现。 This 是一个有效的 C++11 程序。
  • 啊好吧,如果你有时间把它放在 A 中,因为我不清楚你在谈论使用“别名”
  • @NoSenseEtAl 我不是在谈论使用别名。我在谈论使用 any 类型名称。该示例可能只是 template &lt;int&gt; void foo();,工作得很好。
【解决方案2】:

虽然简洁确实是 lambda 的一个卖点,但它并不足以取代对一致性的需求。对于涉及模板的功能尤其如此,因为它们比非模板语言功能更难掌握。

特别是,泛型 lambdas 的模板语法首先具有狭窄的范围,即,大多数 lambdas 可以没有它(实际上,您给出的示例是不将其用作函数体的完美示例不实例化 T 或做类似的事情)。来自P0428(强调我的):

作者认为当前定义泛型 lambda 的语法不够充分的原因有几个。它的要点是,使用普通函数模板可以轻松完成的某些事情需要使用通用 lambda 来完成大量的环跳,或者根本无法完成。

在其主体中使用 decltype 的通用 lambda 可能是新功能最突出的客户。并且在额外的打字和简洁性方面,用&lt;typename T&gt; 替换decltype/decay_t-trickery 对我来说似乎更容易接受。

【讨论】:

    【解决方案3】:

    如果你只是写

    []<T>(){ }
    

    T 是什么?

    typename? auto 值?

    在我看来,在 lambdas 中和在普通函数中一样,有必要明确什么是模板参数。

    如果你可以从使用中推断出T 是一个类型(如果它被用作std::vector 的第一个模板参数必须是一个类型),为什么只简化lambda 语法而不简化传统模板函数的语法?

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2022-01-14
      • 2017-06-22
      • 2011-05-12
      • 1970-01-01
      • 2020-05-20
      • 1970-01-01
      • 2011-01-02
      • 2022-01-04
      相关资源
      最近更新 更多