入力からトークンのストリームを生成する字句スキャナーを書いています。これらのトークンにはtypeとvalueがあります。私は Qt を使用しているので、トークン データを として保存することにしましたQVariant
。これは、非カスタム タイプのトークン データに対して非常にうまく機能します。
残念ながら、トークン内に格納されているカスタム タイプもいくつかあります。トークンには、toString()
(デバッグ用に) トークンの説明を出力する関数がありますが、カスタム型のデータを持つすべてのトークンに対して、この関数は空の文字列を返します。コードは次のようになります。
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("");
}
スキャナからの出力例:
"Token(TT_TEST, )"
"Token(TT_PLUS, +)"
"Token(TT_NUMBER, 5)"
"Token(TT_end, #)"
トークンには Test クラスが含まれており、バリアントがその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
ます。(以前にテンプレートソリューションがありましたが、そこで別の問題に遭遇したため、提案されている場合は例が必要です)。
?