Читаемость кода с лямбдами c ++ 11 - PullRequest
8 голосов
/ 26 мая 2011

Я ДЕЙСТВИТЕЛЬНО люблю лямбды, и иметь возможность использовать их в C ++ - одно удовольствие. Но так как я привык к Haskell, где лямбды действительно хорошо вписываются в синтаксис, я пытаюсь понять, как использовать их в C ++ без написания нечитаемых длинных строк кода.

Итак, в качестве примера предположим, что я напишу это:

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

это не так сложно читать, лямбда-выражение довольно мало. Но если у меня есть функция длиной в две или три строки внутри этого 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 << " ";
          });

или что-то подобное? Я все еще думаю, что этот синтаксис кажется немного неестественным и трудным для чтения ...: (

Ответы [ 6 ]

9 голосов
/ 26 мая 2011

Я обычно хожу на

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

Я написал несколько сотен строчных лямбд.

6 голосов
/ 26 мая 2011

Если вы предпочитаете, вы можете назвать свою лямбду отдельно с помощью auto:

auto const baz = [](double x)
{
    std::cout << "hello!"
    x += bar()/(1+bar());
    std::cout << x << " ";
};
std::for_each(foo.begin(), foo.end(), baz);
3 голосов
/ 27 мая 2011

Хмм ...

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 << " ";
}
2 голосов
/ 26 мая 2011

Мне нравится рассматривать лямбды как просто еще одно объявление функции, и, следовательно, следовать разумным соглашениям, которые я использую для других функций, в пределах разумного:

// 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
1 голос
/ 27 мая 2011

Пост шахты

std::vector<int> a;
std::find_if(a.begin()
           , a.end()
           , [&](int i)
             {
                 return i == 0;
             });
1 голос
/ 26 мая 2011

Я бы сказал, что если лямбда-код состоит из более чем одного или, возможно, двух операторов, это должна быть отдельная именованная функция.

...