Запущение тестов может быть действительно медленным, потому что целая среда направляющих должна загрузиться (попробуйте сценарий/консоль), и только тогда может весь тестовый прогон. Необходимо использовать автотест , который сохраняет среду загруженной и проверит, какие файлы Вы редактируете. Когда Вы отредактируете и сохранили файл, только тесты, которые зависят от них, будут работать автоматически и быстро.
Вы можете использовать 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;
}
}
Кстати, в 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;
}
Предпочитать почти любой другой алгоритм for_each ()
Есть две причины:
Рассмотрим пример из предыдущего ответа:
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"));
"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 ++ для твердых целей.
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_each
like in one of the two first examples.
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.