Я пишу лексический сканер, который генерирует поток токенов из некоторого ввода. Эти токены имеют тип и значение. Поскольку я использую Qt, я решил хранить данные токена как QVariant
. Это работает очень хорошо для данных токена нестандартного типа.
К сожалению, у меня есть несколько пользовательских типов, которые также хранятся внутри токенов. У токенов есть функция toString()
, которая выводит описание токена (для отладки), но для всех токенов, имеющих данные пользовательского типа, эта функция выдает пустую строку. Код выглядит следующим образом:
Тест.ч:
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
. (Ранее у меня было шаблонное решение, но я столкнулся с разными проблемами, поэтому мне понадобится пример, если это будет предложено).
?
qRegisterMetatype
? - person Dmitry Sazonov   schedule 02.06.2014