I'm writing a lexical scanner that generates a stream of tokens from some input. Those tokens have a type and a value. Since I'm using Qt I chose to store the token data as a QVariant
. This works pretty well for token data that is of a non-custom type.
Unfortunately, I have several custom types that are stored inside of tokens as well. The tokens have a toString()
function that outputs a token description (for debugging), but for all tokens that have data of a custom type this function gives an empty string. The code goes like this:
Test.h:
struct Test
{
QString value_;
Test(const QString& value = "");
QString toString();
};
Q_DECLARE_METATYPE(Test)
Token.h:
struct Token
{
TokenType type_;
QVariant value_;
...
virtual QString toString() const;
};
Token.cpp:
QString Token::toString() const
{
QStringList sl;
sl << "Token(" << ::toString(type_) << ", ";
sl << value_.toString() << ")";
return sl.join("");
}
Example output from scanner:
"Token(TT_TEST, )"
"Token(TT_PLUS, +)"
"Token(TT_NUMBER, 5)"
"Token(TT_end, #)"
The TT_TEST
token contains a Test class and I would expect the variant to print it's value. Unfortunately this does not work, and I've tried a lot of solutions that did not work. My current workaround looks like this:
template <typename T>
bool writeToStringList(QStringList& sl, QVariant v)
{
if (!v.canConvert<T>()) return false;
sl << v.value<T>().toString();
return true;
}
and a modified toString()
function:
sl << "Token(";
sl << ::toString(type_) << ", ";
if (!writeToStringList<Test>(sl, value_)) {
sl << value_.toString();
}
and I have to do this for all my custom types which just feels pretty clumsy and wrong.
I figure there must be a better solution to this problem. Can anyone of you:
- Tell me how to solve the problem with the
QVariant
in a better way, or
- suggest a totally different solution without a
QVariant
. (I had a template solution earlier but I ran into different problems there, so I would need an example if that is suggested).
?
See Question&Answers more detail:
os 与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…