Visual C++ "для каждой" переносимости

Я только недавно обнаружил, что Visual C++ 2008 (и, возможно, более ранние версии?) Поддерживает синтаксис for each в списках stl и др., Чтобы облегчить итерацию. Например:

list<Object> myList;

for each (Object o in myList)
{
  o.foo();
}

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

Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
23
0
20 054
9
Перейти к ответу Данный вопрос помечен как решенный

Ответы 9

Ответ принят как подходящий

Для каждого не используется стандартный синтаксис C или C++. Если вы хотите иметь возможность скомпилировать этот код в gcc или g ++, вам нужно будет создать итератор и использовать стандартный цикл for.

QuantumPete

[редактировать] Кажется, это новая функция, представленная в MS Visual C++, поэтому она определенно не переносима. Ссылка: http://msdn.microsoft.com/en-us/library/xey702bw%28VS.80%29.aspx [/ edit]

В Boost Library есть портативный Для каждой реализации.

Есть очень хорошая портативная альтернатива: Boost.Foreach. Просто загрузите этот заголовок в свой проект, и вы сможете писать свои циклы следующим образом:

list<Object> myList;

BOOST_FOREACH(Object o, myList)
    o.foo();

Visual C++ "для каждого" не является стандартным C++, что означает, что вы не сможете скомпилировать свой код на других компиляторах, таких как g ++. Однако STL предлагает std :: for_each, но его синтаксис намного менее интуитивно понятен. Вот его прототип:

template <class InputIterator, class UnaryFunction>
UnaryFunction for_each(InputIterator first, InputIterator last, UnaryFunction f);

Он принимает два итератора, определяющих допустимый диапазон, и применяет унарную функцию (или функтор) f к каждому объекту в этом диапазоне. Вы можете переписать свой пример с помощью std :: for_each следующим образом:

void foo(Object o)
{
  o.foo();
}
...
list<Object> myList;

std::for_each(myList.begin(), myList.end(), foo);

Однако, если вы хотите оставаться ближе к классическому синтаксису для каждой конструкции, и если вы согласны с использованием Boost, вы можете использовать BOOST.FOREACH, что позволит вам написать

list<Object> myList;

BOOST_FOREACH(Object o, myList)
{
    o.foo();
}

Примечание: для каждого (a в b) кажется, что это CLR только в VS 2005/2008 - вы не можете использовать его в собственном коде, только при нацеливании на .NET, что делает для каждого даже «менее переносимым». В остальном я считаю, что ваш ответ отличный.

Suma 13.10.2008 18:23

Также обратите внимание, что если вы используете VS2010, у вас есть лямбда-выражения, и std :: for_each () внезапно становится легко читаемым.

Luis 19.10.2013 01:05

Я голосую за Люка,

Придерживайтесь стандартных алгоритмов STL, и вам будет намного лучше. Алгоритмы STL могут сделать вашу жизнь очень простой, эффективной и безопасной. Взгляните на стандартные алгоритмы, такие как find_if, count, count_if, sort, transform и т. д.

Пункт 5 и далее ... http://www.sgi.com/tech/stl/table_of_contents.html

Boost - это круто, но если вы собираетесь использовать его только для макроса FOR_EACH, это слишком громоздко с точки зрения настройки среды разработки / сборки.

используйте boost, когда стандартный C++ / stl не может решить проблему «простым» способом.

Я также рекомендую BOOST_FOREACH. Обычно я создаю макрос в следующих строках:

#define _foreach(x,y) BOOST_FOREACH(x,y)

Это улучшает читаемость. Однако вы должны быть осторожны с конфликтами с другими реализациями foreach. Например, Qt предоставляет «foreach» и есть std :: for_each.

Я обнаружил, что std :: for_each на самом деле не экономит много времени, поскольку вы в конечном итоге создаете множество одноразовых функциональных объектов для передачи в вызов for_each. Обычно так же быстро можно создать стандартный цикл for с использованием итераторов STL.

В документации Boost.Foreach они явно не рекомендуют писать определение. Вместо этого напишите "#define _foreach BOOST_FOREACH".

Luc Touraille 13.10.2008 18:52

Мне нравится оставлять его как BOOST_FOREACH просто потому, что он напоминает, что это расширение макроса, и нужно быть осторожным с тем, что я помещаю в него.

Ferruccio 14.10.2008 23:38

Я бы не стал этим пользоваться. Хотя это заманчивая функция, синтаксис несовместим с грядущим стандартом C++ 0x, в котором используются:

list<Object> myList;

for (Object o : myList)
{
   o.foo();
}

сделать то же самое.

Если вы хотите использовать foreach и в то же время не хотите добавлять дополнительную зависимость (например, Boost), этот макрос поможет вам:

#define VAR(V,init) __typeof(init) V=(init)
#define FOREACH(I,C) for(VAR(I,(C).begin());I!=(C).end();I++)

std::vector<int> numbers;

FOREACH(I, numbers)
{
    std::cout << *I << std::endl;
}

Ваш код действительно не переносится.

Следующее работает со стандартом C++ 0x и Visual C++ 2010 (который, насколько я могу судить, не поддерживает новый синтаксис «диапазон для»).

#define for_each(_ITER_, _COLL_) for (auto _ITER_ = _COLL_.begin(); \
    _ITER_ != _COLL_.end(); _ITER_++)

Теперь вы можете написать:

list<Object> myList;

for_each (o, myList)
{
  o.foo();
}

Сравните это с кодом макроса BOOST_FOREACH в http://www.boost.org/doc/libs/1_48_0/boost/foreach.hpp, который не только сложен, но и имеет ряд зависимостей от других библиотек повышения.

Другие вопросы по теме