Цикл Foreach у C ++, еквівалентному C #


75

Як перетворити цей код на C ++?

string[] strarr = {"ram","mohan","sita"};    
foreach(string str in strarr) {
  listbox.items.add(str);
}

Відповіді:


123

діапазон на основі :

std::array<std::string, 3> strarr = {"ram", "mohan", "sita"};
for(const std::string& str : strarr) {
  listbox.items.add(str);
}

до c ++ 11

std::string strarr[] = {"ram", "mohan", "sita"};
for(int i = 0; i < 3; ++i) {
  listbox.items.add(strarr[i]);
}

або

std::string strarr[] = {"ram", "mohan", "sita"};
std::vector<std::string> strvec(strarr, strarr + 3);
std::vector<std::string>::iterator itr = strvec.begin();
while(itr != strvec.end()) {
  listbox.items.add(*itr);
  ++itr;
}

Використання Boost :

boost::array<std::string, 3> strarr = {"ram", "mohan", "sita"};
BOOST_FOREACH(std::string & str, strarr) {
  listbox.items.add(str);
}

3
@ronag: Прийнята тут відповідь відображає мою думку про std::for_each.
missingfaktor

2
А як щодо розміру масиву, як for(int i = 0; i < sizeof(strarr)/sizeof(strarr[0]); i++)у першому прикладі коду?
Торбен

оскільки C ++ 11 6 років і 3 стандарти назад, я можу запропонувати перенести частину запитання C ++ 11 на початок. Фактично, припустимо, що C ++ 11 є типовим, і не згадуємо C ++. Замість цього згадайте C ++ 98 для іншого.
болов

@bolov, це відповідь семи років, товаришу. Я не писав C ++ вже шість років. Будь ласка, оновлюйте відповідь, як вважаєте за потрібне.
missingfaktor

@missingfaktor впевнений, не біда
bolov

29

У C ++ 0x у вас є

for(string str: strarr) { ... }

Але до цього часу використовуйте звичайний for loop.


14

Після звикання до varключового слова в C # я починаю використовувати autoключове слово в C ++ 11. Вони обидва визначають тип за умовиводу і корисні, коли ви просто хочете, щоб компілятор з’ясував тип для вас. Ось порт вашого коду на C ++ 11:

#include <array>
#include <string>

using namespace std;

array<string, 3> strarr = {"ram", "mohan", "sita"};
for(auto str: strarr) {
  listbox.items.add(str);
}

5

У Boost є макрос, який зробить це за вас.

http://www.boost.org/doc/libs/1_44_0/doc/html/foreach.html


Я знаю, що Google відмовляє в цьому плані, тому не з вашої вини, але остання версія - 1.44, тому посилання має містити 1_44, а не 1_35. (Вам доведеться виправляти результати Google вручну.)
GManNickG

Дякую. Я завантажив і побудував 1,44 на мою систему, але не розмірковував про версію, коли опублікував її.

5

Просто для розваги (нові лямбда-функції):

      static std::list<string> some_list;

      vector<string> s; 
      s.push_back("a");
      s.push_back("b");
      s.push_back("c");

      for_each( s.begin(), s.end(), [=](string str) 
        {
          some_list.push_back(str);
        }

  );

  for_each( some_list.begin(), some_list.end(), [](string ss) { cout << ss; } );

Хоча рекомендується робити простий цикл :-)


2

Щось на зразок:

const char* strarr = {"ram","mohan","sita", 0L};

for(int i = 0; strarr[i]; ++i)
{
  listbox.items.add(strarr[i]);
}

Також працює для стандартного C. Не впевнений у C ++, як визначити кінець strarr, не маючи нульового елемента, але вищезазначене повинно працювати.


Якщо це статично виділений масив, тоді sizeof(strarr)/sizeof(strarr[0])ви отримуєте кількість елементів у масиві; однак, якщо це динамічно виділений масив (або якщо у вас є лише вказівник), тоді немає способу отримати розмір - його потрібно отримати якимось іншим позасмуговим способом.
Адам Розенфілд,

Правильним типом для розміру (і, отже, індексу в) масиву є std::size_t.
sbi

1

рядок [] strarr = {"ram", "mohan", "sita"};

#include <string>
std::string strarr = { "ram", "mohan", "sita" };

або

const char* strarr[] = { "ram", "mohan", "sita" };

foreach (рядок str у strarr) {listbox.items.add (str); }

for (int i = 0; i < sizeof strarr / sizeof *strarr; ++i)
    listbox.items.add(strarr[i]);

Примітка: ви також можете помістити рядки в std :: vector, а не в масив:

std::vector<std::string> strvec;
strvec.push_back("ram");
strvec.push_back("mohan");
strvec.push_back("sita");

for (std::vector<std::string>::const_iterator i = strvec.begin(); i != strvec.end(); ++i)
    listbox.items.add(*i);

1

Проста форма:

std::string  data[] = {"ram","mohan","sita"};
std::for_each(data,data+3,std::bind1st(std::mem_fun(&Y::add), &(listbox.items)));

Приклад у дії:

#include <algorithm>
#include <string>
#include <iostream>
#include <functional>

class Y
{
    public:
      void add(std::string value)
      {
          std::cout << "Got(" << value << ")\n";
      }
};
class X
{
    public:
      Y  items;
};

int main()
{
    X listbox;

    std::string  data[] = {"ram","mohan","sita"};
    std::for_each(data,data+3,std::bind1st(std::mem_fun(&Y::add), &(listbox.items)));
}

0

Якщо у вас є масив, ви можете просто використати forцикл. (Вибачте, але я не збираюся вводити код для forциклу для вас.)


0

Використання boost - найкращий варіант, оскільки це допомагає вам надати акуратний і стислий код, але якщо ви хочете дотримуватися STL

void listbox_add(const char* item, ListBox &lb)
{
    lb.add(item);
}

int foo()
{
    const char* starr[] = {"ram", "mohan", "sita"};
    ListBox listBox;
    std::for_each(starr,
                  starr + sizeof(starr)/sizeof(char*),
                  std::bind2nd(std::ptr_fun(&listbox_add), listBox));

}

0

за допомогою C ++ 14:

#include <string>
#include <vector>


std::vector<std::string> listbox;
...
std::vector<std::string> strarr {"ram","mohan","sita"};    
for (const auto &str : strarr)
{
    listbox.push_back(str);
}

Чи не можна це скоротити for (const auto &str : {"ram","mohan","sita"} ) ...?
intDattashame
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.