代码可读性与c++11 lambdas

Code readability with c++11 lambdas

本文关键字:lambdas c++11 可读性 代码      更新时间:2023-10-16

我真的很喜欢Lambda,能够在C++中使用它们是一种乐趣。但是,由于我习惯了Haskell,在那里lambdas非常适合语法,我很难在C++中使用它们,而不需要编写不可读的杂乱的长代码行。

因此,作为一个例子,假设我会这样写:

vector<double> foo(10,0.2);
for_each(foo.begin(), foo.end(), [](double x){ std::cout << x << " ";})

这并不难理解,lambda表达式非常小。但是,如果我在for_each中有一个两三行长的函数,这可能会成为我的问题代码阅读技能:

vector<double> foo(10,0.2);
randomNumberGenerator bar;
for_each(foo.begin(), foo.end(), [](double x){ std::cout << "hello!"; x+=bar()/(1+bar()); std::cout << x << " ";})
//sorry, I couldn't think of a less stupid example... 

这句话开始变得长得令人恼火,而且很难按照我的口味阅读。。。

在这种情况下,您首选的代码约定是什么?我应该写:

for_each(foo.begin(), foo.end(), 
          [] (double x) {
                std::cout << "hello!"
                x += bar()/(1+bar());
                std::cout << x << " ";
          });

或者类似的东西?我仍然认为这种语法感觉有点不自然,很难阅读…:(

我通常选择

for_each(foo.begin(), foo.end(), [](double x) {
    std::cout << "hello!"
    x += bar()/(1+bar());
    std::cout << x << " ";
});

我写了一些几百行的lambdas。

如果您愿意,可以使用auto:单独命名您的lambda

auto const baz = [](double x)
{
    std::cout << "hello!"
    x += bar()/(1+bar());
    std::cout << x << " ";
};
std::for_each(foo.begin(), foo.end(), baz);

嗯。。。

for_each(foo.begin(), foo.end(), 
    [] (double x)
    {
        std::cout << "hello!"
        x += bar()/(1+bar());
        std::cout << x << " ";
    });
for (auto x : foo)
{
    std::cout << "hello!";
    x += bar()/(1+bar());
    std::cout << x << " ";
}

我喜欢将lambdas视为另一个函数声明,因此,遵循我用于其他函数的相同约定,这是合理的:

// when lambdas are present, I break the enveloping method params
for_each(
  foo.begin(), 
  foo.end(),           
  [] (double x)
  // I also like to split the brackets, just like with any function
  {
     std::cout << "hello!" 
     x += bar()/(1+bar());                
    std::cout << x << " ";          
  }); // the closing parenthesis is left with the closing bracket

我认为,如果lambda的代码不止一个或两个语句,那么它应该是一个单独的命名函数。

矿井后

std::vector<int> a;
std::find_if(a.begin()
           , a.end()
           , [&](int i)
             {
                 return i == 0;
             });