我正在编写一个词法扫描器,它从一些输入中生成一个令牌流。这些标记有一个type和一个value。由于我使用的是 Qt,因此我选择将令牌数据存储为QVariant
. 这对于非自定义类型的令牌数据非常有效。
不幸的是,我有几个自定义类型也存储在令牌中。令牌具有toString()
输出令牌描述(用于调试)的函数,但对于具有自定义类型数据的所有令牌,此函数会给出一个空字符串。代码如下:
测试.h:
struct Test
{
QString value_;
Test(const QString& value = "");
QString toString();
};
Q_DECLARE_METATYPE(Test)
令牌.h:
struct Token
{
TokenType type_;
QVariant value_;
...
virtual QString toString() const;
};
令牌.cpp:
QString Token::toString() const
{
QStringList sl;
sl << "Token(" << ::toString(type_) << ", ";
sl << value_.toString() << ")";
return sl.join("");
}
扫描仪的示例输出:
"Token(TT_TEST, )"
"Token(TT_PLUS, +)"
"Token(TT_NUMBER, 5)"
"Token(TT_end, #)"
令牌包含一个测试类,TT_TEST
我希望变体打印它的值。不幸的是,这不起作用,我尝试了很多不起作用的解决方案。我当前的解决方法如下所示:
template <typename T>
bool writeToStringList(QStringList& sl, QVariant v)
{
if (!v.canConvert<T>()) return false;
sl << v.value<T>().toString();
return true;
}
和修改后的toString()
功能:
sl << "Token(";
sl << ::toString(type_) << ", ";
if (!writeToStringList<Test>(sl, value_)) {
sl << value_.toString();
}
我必须为我所有感觉很笨拙和错误的自定义类型执行此操作。
我认为必须有更好的解决方案来解决这个问题。你们中的任何人都可以:
- 告诉我如何以
QVariant
更好的方式解决问题,或者 - 建议一个完全不同的解决方案,没有
QVariant
. (我之前有一个模板解决方案,但在那里遇到了不同的问题,所以如果有人建议我需要一个示例)。
?