【问题标题】:Can a generic lambda have no arguments?通用 lambda 可以没有参数吗?
【发布时间】:2015-09-20 09:56:00
【问题描述】:

首先,我知道我可以使用模板类/函子,但这不是我想要的。

这是 lambda:

auto lambda = [] (auto var) {
    decltype(var) x;

    //do stuff with x but nothing with var
};

问题是我收到警告 C4100(未引用的形式参数)。我也知道我可以使用一些技巧,例如禁用警告并在 lambda 之后再次启用它或使用诸如 UNREFERENCED_PARAMETER 之类的宏,但这是作弊。

有什么办法可以做到吗?

理想的代码应该是这样的:

template <typename T>
auto lambda = [] () {
    T x;

    //do stuff with x
};

【问题讨论】:

  • 你使用什么编译器版本?
  • 我正在使用 MSVC 2015 RC。
  • 我很好奇你为什么不想使用 var,因为它已经通过值传递给你,所以它已经是你自己的变量的本地副本。立即宣布另一个喜欢它似乎是多余的。具体来说,varauto,因此它丢失了任何引用属性等,而 xdecltype(var)
  • 好的 - 我现在明白了 - 我读到你的第一行说你不想使用模板。但是你理想的代码是一个模板,所以我想它只是你想要避免的仿函数/类,对不起。
  • 我的代码中真正的 lambda 是不同的,我实际上并没有创建变量,但是我使用 decltype 来访问一个类的静态成员。

标签: c++ lambda c++14


【解决方案1】:

事实上,在 C++14 中,您可以使用您想要的语法创建“模板 lambdas”,但只能在命名空间范围内:

// (1)
template <typename T>
auto l = [] () {
    T x;
};

int main() {
    l<int>();
}

它不是通用 lambda,它是一个变量模板,但你甚至可以创建通用模板 lambda:

template <typename T>
auto l = [] (auto y) {
    T x = 42;
    std::cout << x + y << std::endl;
};

Demo

但是有一个缺点:在当前的编译器中似乎只有 Clang 支持这个。

更新:由于这只能在命名空间范围内完成,如果您的 lambda 没有参数,或者没有 auto 参数(也就是说,它不是通用的),它可以是被一个函数取代,甚至不需要任何 C++11 特性,更不用说 C++14。如果这样的 lambda 有捕获,它们只能捕获全局变量,因此相应的函数可能只是使用相同的变量或它们的副本。感谢@JasonR 指出这一点:

// effectively the same as (1)
template <typename T>
void l() {
    T x;
}

【讨论】:

  • 感谢您的回答,这正是我想要的。
  • @user2565020 我不认为它会对你有帮助,因为 VS2015 doesn't support variable templates。我添加这个答案只是为了完整性。
  • 同意,但我的代码可能要等 2 或 3 年才能完成。
  • 由于 this 只能在命名空间范围内使用,这是否提供了普通函数模板所没有的任何功能?似乎您可以通过使 l 成为函数模板而不是 lambda 来在不使用 C++14 的情况下完成同样的事情,因为 lambda 在这里似乎没有给您带来任何好处。
  • 你能解释一下(用标准参考)为什么这是有效的,而不是像 GCC 5 给出的错误?
【解决方案2】:

如果你真的不需要参数,只需将其包装在void

auto lambda = [](auto var) {
    (void)var; // now we used it - more or less
    decltype(var) x;
    /* whatever else */
};

【讨论】:

  • 不是一个可爱的现代解决方案,但那是因为不存在(除了使用正确的工具来完成工作)。 +1
  • 是的,这正是 UNREFERENCED_PARAMETER 所做的,但感谢您花时间回答。
  • @Barry:哈哈我忘了
【解决方案3】:

不要使用 lambda:

template<typename T>
struct Functor
{
   void operator () () { T var; ... }
}

lambda 不是别的,它是编译器生成的仿函数。

【讨论】:

  • @user2565020:没关系。
【解决方案4】:

这不是 lambdas 的用途,并且没有语法可以做到这一点(除了删除警告)。

只要写一个合适的函数模板。并非所有内容都必须是 lambda。

【讨论】:

    【解决方案5】:

    不,泛型 lambda 不能没有参数,因为它没有参数来推断类型。您将不得不使用后备模板仿函数。

    【讨论】:

      猜你喜欢
      • 2015-03-08
      • 2022-11-17
      • 1970-01-01
      • 2011-11-02
      • 1970-01-01
      • 1970-01-01
      • 2014-06-07
      相关资源
      最近更新 更多