2013-02-26 8 views
5

Se ho una tabella dei simboli:Searching

struct MySymbols : symbols<char, MyEnum::Fruits> 
{ 
    MySymbols() 
     : symbols<char, MyEnum::Fruits>(std::string("MySymbols")) 
    { 
     add("apple", MyEnum::Apple) 
      ("orange", MyEnum::Orange); 
    } 
}; 

voglio iterare sopra il tavolo, al fine di cercare un simbolo dal valore dei dati. Non posso usare le espressioni lambda così ho implementato una semplice classe:

template<typename T> 
struct SymbolSearcher 
{ 
    SymbolSearcher::SymbolSearcher(T searchFor) 
     : _sought(searchFor) 
    { 
     // do nothing 
    } 

    void operator() (std::basic_string<char> s, T ct) 
    { 
     if (_sought == ct) 
     { 
      _found = s; 
     } 
    } 

    std::string found() const { return _found; } 

private: 
    T _sought; 
    std::string _found; 
}; 

E sto usando come segue:

SymbolSearcher<MyEnum::Fruits> search(ct); 
MySymbols symbols; 

symbols.for_each(search); 
std::string symbolStr = search.found(); 

Se ho impostato un punto di interruzione _found = s Posso confermare che _found è sempre impostato , tuttavia search.found() restituisce sempre una stringa vuota. Immagino che abbia qualcosa a che fare con il modo in cui il functor viene chiamato dentro for_each ma non lo so.

Cosa sto sbagliando?

+2

nitpick: la variabile membro deve essere chiarita * _sought * non * _saught * :) – Praetorian

risposta

5

Potrebbe essere che

  • il valore effettivo della stringa è la stringa vuota (improbabile)

  • funtore viene passato per valore, rendendo il funtore stateful inutile (come l'originale lo stato non verrà effettivamente passato).

Si potrebbe rendere il campo _found un riferimento (che richiede di fare in modo di rispettare la regola dei tre per farlo funzionare).

Ecco una dimostrazione che mostra il principio affermando il risultato di un andata e ritorno via SymbolSearcher: http://liveworkspace.org/code/4qupWC$1

#include <boost/spirit/include/qi.hpp> 

namespace qi  = boost::spirit::qi; 

template<typename T> 
struct SymbolSearcher 
{ 
    SymbolSearcher(T searchFor, std::string& result) : _sought(searchFor), _found(result) 
    { 
    } 

    void operator() (std::basic_string<char> s, T ct) 
    { 
     if (_sought == ct) 
     { 
      _found = s; 
     } 
    } 

    std::string found() const { return _found; } 

private: 
    T _sought; 
    std::string& _found; 
}; 

int main() 
{ 
    const std::string str("mies"); 

    typedef std::string::const_iterator It; 
    It begin = str.cbegin(); 
    It end = str.cend(); 

    qi::symbols<char, int> symbols; 
    symbols.add("aap", 1)("noot", 2)("mies", 3); 

    int out; 
    bool ok = qi::parse(begin, end, symbols, out); 
    assert(ok); 

    std::string found; 
    SymbolSearcher<int> sf(out, found); 
    symbols.for_each(sf); 

    assert(str == sf.found()); 
} 
+0

Aggiunta una completamente funzionante [dimostrazione su liveworkspace] (http://liveworkspace.org/code/4qupWC$1) – sehe