ページ 11

構造体のリスト

Posted: 2009年3月06日(金) 16:50
by ちゅん
初めまして、C言語の勉強中の者です。
構造体をリストの末端に書き加える関数を作ろうとしているのですが、上手くいきません。
使用ソフトはMicrosoft VC++で、ソースは以下の通りです。
#include<list>

typedef struct _hoge{
	int x, y, z;
}hoge_t;

std::list<int> *intlist;

hoge_t *hoge_add(int x, int y, int z)
{
	hoge_t *hoge;

	hoge = (hoge_t *)malloc(sizeof(hoge_t)); //メモリ領域確保

	hoge = new hoge_t();
	hoge->x = x;
	hoge->y = y;
	hoge->z = z;

	intlist = intlist->push_back(hoge);

	return hoge;
}
これをビルドすると、以下のように出ます。

error C2664: 'std::list<_Ty>::push_back' : 1番目の引数を 'hoge_t *' から 'const int &' に変換できません。
with
[
 _Ty=int
]
理由: 'hoge_t *' から 'const int' へは変換できません。
この変換が可能なコンテキストはありません。


このソースは自動生成ダンジョンを作ってみたく思い、
こちらのサイト様→http://racanhack.sourceforge.jp/rhdoc/index.html
のソースを自分なりにC++に翻訳しようとしたものです。

なので少し厚かましいとも思いますが、上記のサイト様のソースに沿った方法でご教授願えますでしょうか。
どなたか、宜しくお願いします。

Re:構造体のリスト

Posted: 2009年3月06日(金) 17:13
by SooA
--

Re:構造体のリスト

Posted: 2009年3月06日(金) 17:53
by SooA
すみません、よく見ないで
脊椎反射的に書き込んだので上のは忘れてください><

Re:構造体のリスト

Posted: 2009年3月06日(金) 18:31
by ouh
まず、「構造体をリストの末端に書き加える」ということなので
リストの宣言は
std::list<int> *intlist;
ではなくて構造体のリストにしないと。

あと
hoge_t *hoge;
hoge = (hoge_t *)malloc(sizeof(hoge_t)); //メモリ領域確保
hoge = new hoge_t();
ここは

hoge_t* hoge = new hoge_t;

だけでいいんじゃないでしょうか?

あと、
intlist = intlist->push_back(hoge);
ここですが、
push_back()の戻り値はvoidです。
intlistにpush_back()できるのはintです。


構造体を格納するリストとそのリストへpush_back()する関数を
作るだけなら小難しくポインタ使ったりしなくても
void hoge_add(std::list<hoge_t>& hogehoge, int x, int y, int z) {
    hoge_t hoge;
    hoge.x = x;
    hoge.y = y;
    hoge.z = z;
    hogehoge.push_back(hoge);
}
でよくないですか?

※ご提示のリンク先を全く見ていないので私の言ってることは
もしかしたらまったくのお門違いかもしれません。

Re:構造体のリスト

Posted: 2009年3月06日(金) 18:40
by ouh
せっかくC++なので、hoge_add()を作るのではなく、構造体に
コンストラクタを作っておけばhoge_add()は不要になると思い
ますよ。
struct _hoge {
    int x;
    int y;
    int z;
    _hoge(int _x, int _y, int _z) : x(_x), y(_y), z(_z) {}
} hoge_t;

Re:構造体のリスト

Posted: 2009年3月06日(金) 18:42
by ouh
↑ "struct" の前に typedef 入れるの忘れました...

スレ汚してすみません。

Re:構造体のリスト

Posted: 2009年3月06日(金) 19:40
by ちゅん
>>ouhさん
newには動的確保の項目もあったんですね、見逃していました。


std::list<hoge_t> hogehogeは一度勘で試してみたんですが、それでも

error C2664: 'std::list<_Ty>::push_back' : 1 番目の引数を 'hoge_t *' から 'const hoge_t &' に変換できません。(新しい機能 ; ヘルプを参照)
with
[
_Ty=hoge_t
]
理由: 'hoge_t *' から 'const hoge_t' へは変換できません。
コンストラクタはソース型を持てません、またはコンストラクタのオーバーロードの解決があいまいです。

というエラーが出てしまいます。


>_hoge(int _x, int _y, int _z) : x(_x), y(_y), z(_z) {}
見たことないです。
探そうにも記号が多くて検索に上手く引っかからないし…
良ければ、これの使い方か、これについて詳しく載っているサイトを教えていただけますでしょうか。

Re:構造体のリスト

Posted: 2009年3月06日(金) 20:14
by Mist
> 良ければ、これの使い方か、これについて詳しく載っているサイトを教えていただけますでしょうか。

「初期化リスト」でググってみるとよいでしょう。

Re:構造体のリスト

Posted: 2009年3月06日(金) 20:23
by ちゅん
>>Mistさん
ありがとうございます、早速調べてみます。

Re:構造体のリスト

Posted: 2009年3月06日(金) 20:50
by ouh
私が添付したファイルのコードはコンパイルできると思います。
std::list<hoge_t> hogehoge;
とした場合は、実際にhoge_tを作るときは、
hoge_t* hoge = new hoge_t;
ではなく
hoge_t hoge;
として、
hogehoge.push_back(hoge);
とします。


_hoge(int _x, int _y, int _z) : x(_x), y(_y), z(_z) {}
は、_hoge のメンバである x, y, z をコンストラクタで初期化するときに
こう書きます。
_hoge で言えば、
typedef struct _hoge {
    int x;
    int y;
    int z;
    _hoge(int _x, int _y, int _z) : x(_x), y(_y), z(_z) {}
} hoge_t;
としておけば、実際に _hoge の変数 hoge を宣言するときに
hoge_t hoge(1, 2, 3);
と書けばxを1、yを2、zを3で初期化できます。
宣言と同時に初期化できてしまうので、
hoge_t hoge;
hoge.x = 1;
hoge.y = 2;
hoge.z = 3;
と書かなくてすみます。
そうすればhoge_add()という関数は必要なくなります。

_hoge(int _x, int _y, int _z) {
    x = _x;
    y = _y;
    z = _z;
}
と書くのと同じことです(厳密に言うと同じではないんですが、
結果は同じになります)。

C++の入門書であれば必ずこういうコンストラクタの宣言の仕方が
解説されていると思います。ただし、多分構造体のところではなく
クラスのところで解説されていると思います。

ここに詳しく書かれてました↓
http://www.02.246.ne.jp/~torutk/cxx/con ... index.html

C++ コンストラクタ 初期化子
というキーワードでググるといっぱい見つかります。

Re:構造体のリスト

Posted: 2009年3月06日(金) 21:00
by ouh
hoge_add() を使わないサンプルも添付しておきますね。

Re:構造体のリスト

Posted: 2009年3月06日(金) 21:07
by ouh
どうもそそっかしくてすみません。今回のケースと関連性の低い
URLを提示してしまいました。
こっちの方がよさそうです↓。
http://www.infor.kanazawa-it.ac.jp/~kob ... l/94_.html

Re:構造体のリスト

Posted: 2009年3月06日(金) 21:54
by ちゅん
>>ouhさん
こんなにも尽力くださって、本当にありがとうございます。
初期化リストの件、良く理解できました。

C++はCの上位互換ということで、取り敢えずCの入門書のみを買ってC++はネット頼りとなっております。
その上に勉強を始めてまだ日も浅いので、このようなことを教えていただけると大いに助かります。

コードの方も指示通りにビルドし直したところ、無事にコンパイルできました。
最終目的は自動生成ダンジョンの作成なので、
教えていただいたことを参考にした上でもう一度頑張ってみます。

なので、これにて解決とさせていただきます。
ありがとうございました。