構造体の前方参照

解決


ひる  2009-07-14 10:29:17  No: 70559  IP: [192.*.*.*]

VC2005のC++ですが、
構造体の中で宣言している構造体を前方参照することは可能なのでしょうか?

struct BBBB;       ←これは問題無い
struct BBBB::CCCC; ←ここで「認識できない型 'BBBB' が使われています」と言われる

struct AAAA
{
  BBBB::CCCC* cccc; ←CCCCのポインタを持たせたい
};

struct BBBB
{
  struct CCCC ←CCCCはBBBBの中で宣言している
  {
    int i;
  };

  CCCC cccc;
};

この場合、CCCCをBBBBの外に出したり、
AAAAとBBBBの宣言順を逆にすれば通るのは理解していますが、
上記の構造のままではできないものなのでしょうか。

編集 削除
ひる  2009-07-14 10:31:02  No: 70560  IP: [192.*.*.*]

すみません、タブ文字が削除されてしまったので、
全角スペースに置き換えて再投稿させていただきます。

VC2005のC++ですが、
構造体の中で宣言している構造体を前方参照することは可能なのでしょうか?

struct BBBB;       ←これは問題無い
struct BBBB::CCCC; ←ここで「認識できない型 'BBBB' が使われています」と言われる

struct AAAA
{
    BBBB::CCCC* cccc; ←CCCCのポインタを持たせたい
};

struct BBBB
{
    struct CCCC ←CCCCはBBBBの中で宣言している
    {
        int i;
    };

    CCCC cccc;
};

この場合、CCCCをBBBBの外に出したり、
AAAAとBBBBの宣言順を逆にすれば通るのは理解していますが、
上記の構造のままではできないものなのでしょうか。

編集 削除
aetos  2009-07-14 14:04:39  No: 70561  IP: [192.*.*.*]

> 上記の構造のままではできないものなのでしょうか。

そうしたい意図が不明です。
CCCC の宣言を BBBB の中に入れるのは、CCCC は BBBB の中でしか使わないからであろうと一般には思われます。
が、それを AAAA から使おうという時点で、何を考えているのかわかりません。

編集 削除
仲澤@失業者  2009-07-14 17:41:53  No: 70562  IP: [192.*.*.*]

何に使うのかさっぱり意味不明ですが、一般論として、
typedef を使って「型」定義すれば好きに参照できますよね。
提示のコードは、そもそも前方参照しなければいけないような
ものでもないと思いますが(CCCCを前に持ってくるだけでOK)、
無理やり書くと

struct CCCC; //宣言のみ
typedef struct AAAA{ CCCC* cccc;}AAAA;
typedef struct CCCC{ int i; }CCCC;
typedef struct BBBB{ CCCC cccc; }BBBB;

編集 削除
ひる  2009-07-14 18:49:45  No: 70563  IP: [192.*.*.*]

おとなしくCCCCをBBBBの外に出してしまいます。
ありがとうございます。

自分でも一日中ネットを探し回っていましたが、
同じような問題を提示されているかたがおられ、
C++ではできないという結論になっていました。
http://ml.tietew.jp/cppll/cppll/article/9653

編集 削除
wclrp ( 'o')  2009-07-14 23:00:08  No: 70564  IP: [192.*.*.*]

俺も同じ目にあったことある。
仕方ないから外に出すしかないのかな。

CCCCがありがちな名前の場合
BBBB_CCCCみたいな変な名前にしたくないんだよな。
まあstd::vectorという書き方も好きじゃあないけど。

編集 削除
yoh2  2009-07-14 23:01:56  No: 70565  IP: [192.*.*.*]

ふと思い付いた冗談バージョン。

template<typename T>
struct AAAA_
{
    typename T::CCCC* cccc;
};

// BBBBをテンプレート引数にしてtypedef宣言するだけなら
// BBBBは前方宣言のみでOK。
struct BBBB;
typedef AAAA_<BBBB> AAAA;

struct BBBB
{
    struct CCCC
    {
        int i;
    };

    CCCC cccc;

    // おまけ
    // ここにAAAAのインスタンスを宣言するという無茶
    // (定義順の入れ替えでは対応できないと思う)も可能。
    AAAA aaaa;
};

// ここから先でAAAAを使うことができる。
AAAA aaaa;

編集 削除
ryo  2009-07-15 00:19:07  No: 70566  IP: [192.*.*.*]

プログラムだと、

C:小分類
B:中分類(小分類を含む)
A;大分類(中・小分類を含む)

って順番に書くけど、
この流れがなんとなくスッキリ受け入れられないだけじゃないかな

編集 削除
ひる  2009-07-21 09:09:03  No: 70567  IP: [192.*.*.*]

> CCCCがありがちな名前の場合
> BBBB_CCCCみたいな変な名前にしたくないんだよな。

まさにこれと同じ理由でした。
CCCCを外に出すと、BBBB_CCCCみたいな名前になりますよね。

実際のソースでは、AAAAとBBBBにあたるものは別ヘッダにあり、
実体ではなくポインタをメンバや引数に持つ場合には、
ヘッダ内ではインクルードせずに前方宣言するべきだと習ったので、
AAAA.h内でstruct BBBB::CCCC;と書きたかったのですが、
こういうふうには記述できないことがわかりました。
ありがとうございます。

編集 削除