C++ STL - выполните итерации через все в последовательности

Запущение тестов может быть действительно медленным, потому что целая среда направляющих должна загрузиться (попробуйте сценарий/консоль), и только тогда может весь тестовый прогон. Необходимо использовать автотест , который сохраняет среду загруженной и проверит, какие файлы Вы редактируете. Когда Вы отредактируете и сохранили файл, только тесты, которые зависят от них, будут работать автоматически и быстро.

5
задан Angus 26 September 2009 в 03:53
поделиться

6 ответов

Вы можете использовать for_each из стандартной библиотеки. Вы можете передать ему функтор или функцию. Мне нравится решение BOOST_FOREACH , которое аналогично foreach на других языках. У C + 0x будет один кстати.

Например:

#include <iostream>
#include <vector>
#include <algorithm>
#include <boost/foreach.hpp>

#define foreach BOOST_FOREACH 

void print(int v)
{
    std::cout << v << std::endl;
}

int main()
{
    std::vector<int> array;

    for(int i = 0; i < 100; ++i)
    {
        array.push_back(i);
    }

    std::for_each(array.begin(), array.end(), print); // using STL

    foreach(int v, array) // using Boost
    {
        std::cout << v << std::endl;
    }
}
12
ответ дан 18 December 2019 в 08:29
поделиться

Кстати, в MSVS 2008 есть ключевое слово C ++ «для каждого». См. Как выполнить итерацию по коллекции STL для каждого .

int main() {
   int retval = 0;

   vector<int> col(3);
   col[0] = 10;
   col[1] = 20;
   col[2] = 30;

   for each( const int& c in col )
      retval += c;

   cout << "retval: " << retval << endl;
}
1
ответ дан 18 December 2019 в 08:29
поделиться

Предпочитать почти любой другой алгоритм for_each ()

Есть две причины:

  1. for_each является чрезвычайно общим, ничего не сообщает вам о том, что на самом деле делается, только о том, что вы делаете что-то для всех элементов в последовательности.
  2. Более специализированный алгоритм часто будет более простым и прямым.

Рассмотрим пример из предыдущего ответа:

void print(int v)
{
    std::cout << v << std::endl;
}
// ...
std::for_each(array.begin(), array.end(), print); // using STL

Использование std :: copy вместо этого превращает все это в :

std :: copy (array.begin (), array.end (), std :: ostream_iterator (std :: cout, "\ n"));

0
ответ дан 18 December 2019 в 08:29
поделиться
"struct functor {
  void operator()(Foo& arg){
    blah(arg.x, arg.y);
    woop(arg.z);
  }
};

std::for_each(someVariable.begin(), someVariable.end(), functor());"

Я думаю, что подобные подходы часто излишне бесполезны для простых задач.

do i=1,N
 call blah( X(i),Y(i) )
 call woop( Z(i) )
end do

совершенно ясно, даже если прошло 40 лет старый (а не C ++, очевидно).

Если контейнер всегда является вектором (имя STL), я не вижу ничего плохого в индексе и ничего плохого в том, чтобы назвать этот индекс целым числом.

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

Что касается пунктов 2 и 3 SSS выше, я бы сказал, что это может быть так и в сложных случаях, но часто повторение 1 ... N часто так же просто и понятно, как и все остальное.

Если вам нужно было объяснить алгоритм на доске, могли бы вы сделать это быстрее с помощью или без использования «i»? Я думаю, что если ваше объяснение «мясного пространства» яснее с указателем, используйте его в кодовом пространстве.

Сохраните тяжелую огневую мощь C ++ для твердых целей.

0
ответ дан 18 December 2019 в 08:29
поделиться

Not counting BOOST_FOREACH which AraK already suggested, you have the following two options in C++ today:

void function(Foo& arg){
  blah(arg.x, arg.y);
  woop(arg.z);
}

std::for_each(someVariable.begin(), someVariable.end(), function); 

struct functor {
  void operator()(Foo& arg){
    blah(arg.x, arg.y);
    woop(arg.z);
  }
};

std::for_each(someVariable.begin(), someVariable.end(), functor());

Both require you to specify the "body" of the loop elsewhere, either as a function or as a functor (a class which overloads operator()). That might be a good thing (if you need to do the same thing in multiple loops, you only have to define the function once), but it can be a bit tedious too. The function version may be a bit less efficient, because the compiler is generally unable to inline the function call. (A function pointer is passed as the third argument, and the compiler has to do some more detailed analysis to determine which function it points to)

The functor version is basically zero overhead. Because an object of type functor is passed to for_each, the compiler knows exactly which function to call: functor::operator(), and so it can be trivially inlined and will be just as efficient as your original loop.

C++0x will introduce lambda expressions which make a third form possible.

std::for_each(someVariable.begin(), someVariable.end(), [](Foo& arg){
  blah(arg.x, arg.y);
  woop(arg.z);
});

Finally, it will also introduce a range-based for loop:

for(Foo& arg : my_someVariable)
{
  blah(arg.x, arg.y);
  woop(arg.z);
}

So if you've got access to a compiler which supports subsets of C++0x, you might be able to use one or both of the last forms. Otherwise, the idiomatic solution (without using Boost) is to use for_eachlike in one of the two first examples.

5
ответ дан 18 December 2019 в 08:29
поделиться

Prefer algorithm calls to hand-written loops

There are three reasons:

1) Efficiency: Algorithms are often more efficient than the loops programmers produce

2) Correctness: Writing loops is more subject to errors than is calling algorithms.

3) Maintainability: Algorithm calls often yield code that is clearer and more
straightforward than the corresponding explicit loops.

1
ответ дан 18 December 2019 в 08:29
поделиться
Другие вопросы по тегам:

Похожие вопросы: