通用lambdas:语法糖或不?

时间:2014-08-19 11:33:32

标签: c++ lambda syntactic-sugar c++14 generic-lambda

C ++ 14泛型lambda是否真正改善了语言,或者它们是一种语法糖?

是否存在某些情况
[](auto param1, auto param2, /* ... */ auto paramN)
{
    return /* ... */;
}

不能替换为

template <typename Type1, typename Type2, /* ... */ typename TypeN>
auto foo(Type1&& param1, Type2&& param2, /* ... */ TypeN&& paramN)
{
    return  /* ... */;
}

struct bar
{
    template <typename Type1, typename Type2, /* ... */ typename TypeN>
    auto operator()(Type1&& param1, Type2&& param2, /* ... */ TypeN&& paramN)
    {
        return  /* ... */;
    }
};


@Kerrek SB提供了非常有趣的链接in the comments,它说明了通用lambda的力量:

3 个答案:

答案 0 :(得分:3)

对于C ++ 11的非泛型lambda表达式,可以执行一些简单的转换:

void foo()
{
    int i = 42; int j = 22;
    auto f = [i, &j](int k) { return i + j + k };
    // proceed to use f
 }

例如:

void foo()
{
    int i = 42; int j = 22;
    struct {
        int i; int& j;
        // can't deduce return type
        int operator()(int k) const
        { return i + j + k; }
    } f { i, j };
    // proceed to use f
}

对于C ++ 14的通用lambda表达式,它并不那么简单。假设这次我们正在使用auto f = [i, &j](auto k) { return i + j + k; }。然后我们必须生成以下调用运算符:

template<typename T>
auto operator()(T k) const { return i + j + k; }

问题是我们无法在功能范围定义模板(限制也称为无本地模板)。因此,我们必须将封闭类型定义从封闭函数移出到命名空间范围(在过程中为其命名),然后使用closure_type f { i, j };。顺便说一句,这意味着我们必须为类及其运算符提供某种形式的链接,而函数本地定义没有链接。

所以从某种意义上说,泛型lambda表达式为我们提供了一个有限版本的本地函数模板。

答案 1 :(得分:1)

一般关于Lambdas:

  

有些人认为这真的很整洁!&#34 ;;其他人认为这是编写危险的模糊代码的一种方式。 IMO,两者都是对的。 --- Bjarne Stroustrup

我认为这是一个关于如何使用lambda的问题。作为一个小的局部闭包函数,你用它来改进函数的处理,它将函数对象作为参数(比如std::sort),我还没有真正看到一个例子,通用lambda会增加任何好处。 / p>

如果你使用它们在C ++中编写类似haskell的代码,那么它会增加一些好处,但是我看到了太多的代码示例,其中对象的生命周期至少被部分忽略了。所以我不认为它会增加一个好处。

让我解释一下:

void foo(std::vector<int>& v)
{
    std::sort(v.begin(), v.end(), [](int i, int j) { return (i < j); });
}

这是一个真正的改进,但注册了一个回调,稍后会调用,也可能在另一个线程中调用:

void C::foo()
{
    registerLazyMultithreadedCallback([=this]() { return this; });
}

这会使事情变得复杂,因为你必须确保你返回的对象是有效的。这可能导致荒谬的情况(例如在破坏后短时间内召唤)。我的经验是,在编写没有lambda的构造之前,编码人员会三思而行。

因此,如果您仅在本地使用它们作为辅助函数,则不需要泛型,因为所有类型都是明确的。

我想我就是其中之一,他们认为你可以用lambda编写危险的模糊代码。

答案 2 :(得分:0)

  

C ++ 14通用lambda是否真正改善了语言

  

或者它们是一种语法糖?

你似乎暗示语法糖并不是对语言的真正改进。请记住,语言本身就是语法糖。您可以在机器代码中编写所有内容:)