c как выполнить итерацию по коллекции объектов без явно созданного контейнера с возможностью повторения

#c

#c

Вопрос:

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

 object_type a, b, c; 
// do sth with objects a, b, c

for (auto amp;x in {a, b, c}) 
{ // do }; // wish: be able to loop over objects via on-the-fly-container {a, b, c}
  

вопросы:

  1. как я могу реализовать вид цикла в примере наиболее кратким / элегантным способом?

  2. как правило, с однотипными элементами: можно ли создавать неявно определенные векторы? кортежи? какой-либо контейнер вообще?

Спасибо

Комментарии:

1. Вы также хотите иметь возможность изменять объекты в цикле?

2. @cigien, на самом деле не требуется, но я думаю, что ссылки могут быть более эффективными с большими объектами?

3. Конечно, это определенно более эффективно, но обратите внимание, что переменная цикла не является ссылкой на фактические объекты.

4. @cigien, ах, потому что эти объекты уже скопированы в {a, b, c}?

5. @cigien Не уверен, что это обязательно более эффективно. Если компилятор может выяснить, как избежать копирования, косвенное обращение через ссылку на самом деле может быть (слегка) хуже.

Ответ №1:

Вы можете просто выполнить итерацию по списку инициализаторов, содержащему объекты:

 for(auto o : {a, b, c})
  // ...
  

Вот демонстрация.

Вы также могли бы написать auto amp;o , но обратите внимание, что o это не ссылка на фактические объекты a , b и c , поэтому вы не сможете их изменять. Если вы хотите это сделать, вы могли бы написать это таким образом:

 for(auto *o : {amp;a, amp;b, amp;c})
   // *o is the object
  

где вы выполняете итерацию по адресам объектов.

Вот демонстрация.

Комментарии:

1.Что касается записи в ссылку. C фактически применяет постоянную ссылку в этой точке. Это for (autoamp; x: {y}) x = z; приведет к ошибке компилятора.

Ответ №2:

Вы почти правильно выполнили для каждого цикла:

 for (autoamp; x: {a, b, c}) {
}
  

Вы также можете превратить это выражение в вектор:

 auto stuff = std::vector<object_type>{a, b, c};
  

И начиная с C 17, вы даже можете заставить C определять тип вектора:

 auto stuff = std::vector{a, b, c};