1

テンプレート化された構造体のコレクションを保持するように QList を定義できますか?各構造体は異なる型で定義されていますか??

検討:

template<typename T>struct AA
{
  T value;
}

AA の異なるインスタンスを保持するように QList を宣言できますか?? 何かのようなもの:

struct<int> myIntStruct;
myIntStruct.value = 10;
struct<double> myDobleStruct;
myDoubleStruct = 12.2;

template<typename T>
QList<struct AA<T>> myList;
myList.push_back(myIntStruct);
myList.push_back(myDoubleStruct);

私の意見では、QList には (テンプレート化されたオブジェクトの場合でも) 同じデータ型のエンティティを含める必要があるため、上記の操作は違法です。その場合、そのような操作を行うためにQtでどの構造を使用できますか??

ありがとう、

ヴィシュヌ。

4

4 に答える 4

2

コンテナに異なるオブジェクトを持たせたい理由は、おそらく設計上の欠陥です。ただし、異なるオブジェクト タイプの混合を含むことができるバッグ コレクションの概念を持つ Smalltalk など、一部の言語はこれをサポートします。Qt には何らかのバッグ コンテナー クラスが既にある可能性がありますが、その存在を知りません。

単一のコンテナー内に型が混在するというこの概念は、厳密に型指定された C++ の世界ではうまく機能しません。QVariantバリアントオブジェクトは最も近いものであり、サブクラス化して構造体を処理するためにいくつかのビットを追加することで実行できる独自の「スーパーバリアント」クラスを作成しない限り、非整数型の場合でもそうではありません。

なぜこの機能が必要なのか、もう一度自問自答してください。他の場所で実装されたより単純なソリューションは、おそらくそのようなコンテナーの必要性を軽減します。

QMap<QString, QVariant>編集:それが機能するかどうかを判断するのに役立つQuickieの例。

class SomeObject
{
public:
    SomeObject() // default
        : someInt(0), someDouble(0) {}
    SomeObject(int i, double d) // explicit
        : someInt(i), someDouble(d) {}

    int GetSomeInt() const { return someInt; }
    double GetSomeDouble() const { return someDouble; }

private:
    int someInt;
    double someDouble;
};

// must be outside of namespace
Q_DECLARE_METATYPE(SomeObject)

// then you can do stuff like this:
    QMap<QString, QVariant> mapNameToValue;

    // populate map
    mapNameToValue["UserName"] = "User";
    mapNameToValue["Port"] = 10101;
    mapNameToValue["PI"] = 3.14159265;
    mapNameToValue["DateTime"] = QDateTime::currentDateTime();
    QVariant userValue;
    userValue.setValue(SomeObject(5, 34.7));
    mapNameToValue["SomeObject"] = userValue;

    // read from map
    QString userName = mapNameToValue["UserName"].toString();
    unsigned int port = mapNameToValue["Port"].toUInt();
    double PI = mapNameToValue["PI"].toDouble();
    QDateTime date = mapNameToValue["DateTime"].toDateTime();
    SomeObject myObj = mapNameToValue["SomeObject"].value<SomeObject>();

    int someInt = myObj.GetSomeInt();
    double someDouble = myObj.GetSomeDouble();

QVariant多くの型を処理し、テンプレート メソッドsetValuevalue<>ユーザー定義型も備えています。上記で簡単に示したように、Q_DECLARE_METATYPEマクロを使用して登録し、変換が失敗QMetaTypeした場合に備えてデフォルトのコンストラクターを提供する必要があります。value<>特定の比較演算子をサポートしないので、独自のバージョンのQVariantandを作成して、QMetaType必要な追加の型をうまく操作して、より一貫性を感じられるようにします。

于 2011-03-31T20:56:53.667 に答える
1

テンプレート クラスはクラスではなく、テンプレートです。これを使用して、やなど、まったく関係のないクラスをインスタンス化できます。AA<int>AA<double>

探している機能を取得するには (無関係なクラスをコンテナに追加する)、そのような無関係なインスタンスの追加を特にサポートするコンテナが必要か、オブジェクトをラップする必要があります。boost::variant

于 2011-03-31T19:57:40.210 に答える
0

とは別々のデータ型MyTemplateClass<int>MyTemplateClass<double>見なされるため、両方の型を同時に含むQListを作成することはできないと思います。

ただし、オプションがあります。単純なデータ型を格納するだけの場合は、QVariantを確認してください。これは単一のクラス型ですが、ユニオンを使用してさまざまなデータ型を内部に保持します。すでにQtを使用しているので、組み込みです。

より複雑なものを格納しようとしている場合は、おそらくポリモーフィッククラスが最適です。次に、sのQListを作成MyBaseType*し、リストから呼び出す必要のあるすべての関数をに設定できますvirtual。MyBaseTypeをQVariantから継承させることもできるので、データストレージが自動的に処理されます。

お役に立てれば!

于 2011-03-31T20:01:08.483 に答える
0

一般に、同じコンテナー内に同種でない型を含めることはできないというのは正しいことです。

boost::any(スマート) ポインターのコンテナーでそれを回避できますboost::variant

于 2011-03-31T19:59:03.637 に答える