2013-12-26 3 views
2

EDIT: Я сдаюсь! Сейчас я использую просто for (string& word : sentence) { .. }. BOOST_FOREACH безнадежно. Спасибо.Как сделать мой класс итерабельным BOOST_FOREACH в C++?

Я читал this и this, и они вообще не помогли. Особенно хочу спросить о второй ссылке. Почему вы должны определить некоторые странные структуры в пространстве имен boost? Класс, который я хочу включить BOOST_FOREACH для, определяется в моем собственном пространстве имен. Как я могу получить доступ к данным из этого класса, если я определяю свои итераторы в namespace boost { .. }? Это не имеет никакого смысла. Я не знаю, почему найти эквивалентность IEnumerable в C++ заняло у меня столько времени! Wans't boost должен был сэкономить мое время?

Может кто-нибудь сказать мне просто опрятному способ перебрать этот класс:

class Sentence { 
private: 
    vector<string> words; 
} 

с этим кодом:

Sentence sentence; 
BOOST_FOREACH(string word, sentence) { 
    // .. 
} 

Спасибо.

+0

Этот фрагмент из ответа * вы * связали со значительным количеством его сумм: если вы определили класс итератора, вам просто нужно добавить функции begin() и end() для вашего класса. – Borgleader

+0

Класс 'Sentence' определен в собственном пространстве имен. Как я могу получить доступ к словам (которые не только в другом пространстве имен, но и в частном члене) из тех итераторов, определенных в пространстве имен 'boost'? –

ответ

3

Согласно the documentation, все, что похоже на стандартный контейнер библиотеки, будет работать. Самый простой способ - разоблачить пару итераторов в вашем классе. Если вы не хотите, чтобы реализовать свой собственный, просто использовать vector<string> итераторы:

class Sentence 
{ 
public: 
    typedef vector<string>::iterator iterator; 
    typedef vector<string>::const_iterator const_iterator; 
    const_iterator begin() const { return words.begin(); } 
    const_iterator end() const { return words.end(); } 
private: 
    vector<string> words; 
}; 

Редактировать кажется BOOST_FOREACH не достаточно умен, чтобы понять стандартные библиотечные контейнероподобные типы, но это можно понять пару стандартной библиотеки итераторы. Таким образом, дополнительный шаг необходим:

#include <iostream> 
#include <utility> 
int main() 
{ 
    Sentence sentence; 
    auto s = std::make_pair(sentence.begin(), sentence.end()); 
    BOOST_FOREACH(std::string word, s) { 
    std::cout << word << std::endl; 
    } 
} 

Примечание 1: Вы можете разъединяют явный тип итератора с помощью типа стирания, но это можно было бы рассматривать как уточнение. См. this relevant discussion для получения дополнительной информации.

Примечание 2: Я никогда не был большим поклонником BOOST_FOREACH. Контуры, основанные на диапазоне C++ 11, делают еще менее вероятным, что я буду использовать его в реальном коде.

+0

Я пробовал это. Но это поддерживает только синтаксис C++ 11 foreach ('for (string word in sentence') .Он не поддерживает BOOST_FOREACH. –

+0

@SMTNinja Вы правы, это не так умно, как я предполагал. Он работает с парой итераторов, но я бы предпочел цикл, основанный на диапазоне. – juanchopanza

Смежные вопросы