如果我有符号表:
struct MySymbols : symbols<char, MyEnum::Fruits>
{
MySymbols ()
: symbols<char, MyEnum::Fruits>(std::string("MySymbols"))
{
add("apple", MyEnum::Apple)
("orange", MyEnum::Orange);
}
};
我想迭代表格,以便按数据值搜索符号。我不能使用lambda表达式,所以我实现了一个简单的类:
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;
};
我正在使用它如下:
SymbolSearcher<MyEnum::Fruits> search(ct);
MySymbols symbols;
symbols.for_each(search);
std::string symbolStr = search.found();
如果我在_found = s
上设置断点,我可以确认_found已经设置,但是search.found()总是返回一个空字符串。我猜它与for_each中调用functor的方式有关,但我不知道。
我做错了什么?
答案 0 :(得分:5)
可能是那个
字符串的实际值是空字符串(不太可能)
仿函数通过值传递,使状态仿函数无用(因为原始状态实际上不会被传递)。
您可以将_found
字段作为参考(要求您确保遵守“三次规则”以使其正常工作)。
以下是通过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());
}