If I have a symbol table:
struct MySymbols : symbols<char, MyEnum::Fruits>
{
MySymbols ()
: symbols<char, MyEnum::Fruits>(std::string("MySymbols"))
{
add("apple", MyEnum::Apple)
("orange", MyEnum::Orange);
}
};
I want to iterate over the table in order to search for a symbol by data value. I cannot use lambda expressions so I implemented a simple class:
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;
};
And I'm using it as follows:
SymbolSearcher<MyEnum::Fruits> search(ct);
MySymbols symbols;
symbols.for_each(search);
std::string symbolStr = search.found();
If I set a breakpoint on _found = s
I can confirm that _found is getting set, however search.found() always returns an empty string. I'm guessing it has something to do with the way the functor is being called inside for_each but I don't know.
What am I doing wrong?
It could be that
the actual value of the string is the empty string (unlikely)
the functor is being passed by value, making the stateful functor useless (as the original state will not actually be passed).
You could make the _found
field a reference (requiring you to make sure to respect the Rule-Of-Three to make it work).
Here's a demonstration that shows the principle by asserting the result of a roundtrip 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());
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With