【问题标题】:Specifying a lambda function as default argument将 lambda 函数指定为默认参数
【发布时间】:2011-05-17 00:51:01
【问题描述】:

如何将 lambda 指定为默认参数?我想这样做:

int foo(int i, std::function<int(int)> f = [](int x) -> int { return x / 2; })
{
    return f(i);
}

但我的编译器(Mac OS X 上的 g++ 4.6)抱怨:

error: local variable 'x' may not appear in this context

编辑: 事实上,这是一个编译器错误。上述代码适用于最新版本的 gcc (4.7-20120225)。

【问题讨论】:

  • 我想知道这是 gcc 的问题还是标准禁止它。
  • 补充一点,MSVC (2010) 发出相同的警告:error C2587: 'x' : illegal use of local variable as default parameter - see declaration of 'x'。似乎是因为参数,如果我从 lambda、std::function 和函数调用中删除它,它编译得非常好。
  • @Xeo:我想知道 VC2011 对这种语法有何反应,因为它改进了 lambda 支持。
  • 现在(2017 年 2 月 24 日)通过 clang++ -c -std=c++11 与 clang-800.0.42.1 一起工作

标签: c++ lambda c++11


【解决方案1】:

你可以使用重载:

int foo(int i)
{
    return foo(i, [](int x) -> int { return x / 2; });
}

int foo(int i, std::function<int(int)> f)
{
    return f(i);
}

【讨论】:

  • 像 Matthieu 一样,我不确定这个问题是 gcc 中的错误还是故意的。您的解决方法似乎是目前最好的解决方案。
  • 啊,java风格的默认参数。眼睛酸痛的景象(不是!)
【解决方案2】:

这似乎是 gcc 中的一个错误;只要没有捕获任何内容,该标准就允许在默认参数中使用 lambda 表达式。

以下似乎是 FDIS 关于默认参数中 lambda 的所有内容,因此默认情况下应允许除此处禁止的内容之外的任何使用。

C++11 FDIS 5.1.2/13

出现在 a 中的 lambda 表达式 默认参数不应隐含 或显式捕获任何实体。

[示例:

void f2() {
    int i = 1;
    void g1(int = ([i]{ return i; })());       // ill-formed
    void g2(int = ([i]{ return 0; })());       // ill-formed
    void g3(int = ([=]{ return i; })());       // ill-formed
    void g4(int = ([=]{ return 0; })());       // OK
    void g5(int = ([]{ return sizeof i; })()); // OK
}

—结束示例]

【讨论】:

  • 请注意,在所有这些示例中都没有参数,这就是编译器窒息的原因(即使在 VS2010 中)。
  • @Xeo - 是的,但标准中没有任何地方明确禁止 lambda 中的参数用作默认参数(这确实是一个非常愚蠢的限制),所以两个编译器都只是错误。
  • 这些例子略有不同——它们是执行一个lambda来获得一个函数参数的默认值;这真的意味着 lambda 本身可以是默认值吗?
  • @ildjarn - 示例本身是非规范性的,但语法清楚地允许默认参数是 lambda 表达式,并且 AFAICS 不存在专门对语法所说的内容进行例外的规范性文本.
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-12-12
  • 1970-01-01
  • 1970-01-01
  • 2011-03-24
相关资源
最近更新 更多