8

次の循環依存関係を解決するにはどうすればよいですか?

typedef boost::variant<int, bool, double, std::string, Structure> Value;
typedef std::list<std::pair<std::string, ValueContainer>> Structure;
typedef std::vector<Value> ValueContainer;

CapiデータベースライブラリのオブジェクトをよりC++形式で表現しようとしています。このデータベースを使用すると、次のように、値または値の配列を格納したり、構造体を表現したりできます。

typedef struct ApiStructureMember 
{
    char* name;
    struct ApiValueContainer value;
    struct ApiStructureMember_T* next;
} ApiStructureMember_T;

最後に、次のように、ユニオンを使用して値を表します。

typedef struct ApiValue 
{
    union 
    {
        int i;
        const char*   s;
        ...
        struct ApiStructureMember_T* firstStructureMember;
    } value;
} ApiValue_T; 
4

2 に答える 2

5

相互に含むタイプを持つことはできません。考えてみてください。コンパイラは、データを生成する無限ループに入ります。

2つの一般的なパターンがあります。1つは、相互にポイントするデータ型を使用するパターンです。

struct OddNode; // forward declaration

struct EvenNode 
{
    OddNode* prev;
    OddNode* next;
};

struct OddNode
{
    EvenNode* prev;
    EvenNode* next;
};

ポインターを省略し、値による包含を使用して偶数ノードと奇数ノードを実装すると、コンパイラーは定義を解決できなくなります。

一般的には、データを表すボックスとさまざまな部分を結ぶ線を使用して、データをどのようにレイアウトするかを描くだけです。次に、各ボックスをクラスに置き換え、各行を対応するクラスへのポインターに置き換えます。どこかに循環依存がある場合は、コードの先頭でクラスを前方宣言するだけです。

2番目の循環依存関係は、Curiously Recurring Template Parameter(CRTP)を介したものです。

template<typename T> 
struct Y 
{};

struct X
: 
    public Y<X> 
{};

Structureあなたの例は、 asXstd::list< ..., Structure>asでCRTPを使用することY<X>です。

于 2012-08-09T14:04:40.650 に答える
2

これは解決策ではありませんか?

class Structure;
typedef boost::variant<int, bool, double, std::string, Structure> Value;
typedef std::vector<Value> ValueContainer;

class Structure: public std::list<std::pair<std::string, ValueContainer>>
{
};
于 2012-08-09T14:16:19.957 に答える