- ベストアンサー
BCB6でのエラー…
BCB6のMEMOコンポーネントに、プログラムの実行結果を表示したく、ButtonClickイベントにプログラムを書き、実行すると 「テンプレート引数に、静的リンゲージまたはローカルリンゲージを入れることはできない」 というエラーが出てしまいます。プログラムを添付致しますのでよろしかったらご覧になって下さい。 struct State { // 状態を表すフラグ // false は、川の左岸、true は、川の右岸を表わす bool wolf; bool goat; bool cabbage; bool man; // この状態になるまでの道のり deque<State> path // -------- 初期化 -------- // 初期状態では、全て川の左岸 State() : wolf( false ), goat( false ), cabbage( false ), man( false ), path() { } // -------- 状態に対するオペレーター ------ // 狼を移動させる State move_wolf() const { State s = *this; s.path.push_back( *this ); if ( s.wolf == s.man ) { s.wolf = !s.wolf; s.man = !s.man; } return( s ); } のように続きます。 deque<State> pathの部分にエラーが表示されます。 初心者で全く分からないので、プログラム等、不明な点があればお答え致しますので、どうか分かる方いましたらお返事をよろしくお願いいたします。
- みんなの回答 (6)
- 専門家の回答
質問者が選んだベストアンサー
クラス設計の巧拙はひとまずおき、純粋に可否で言えば、質問のコードそのものにコンパイル不能になるような問題はありません。 >ButtonClickイベントにプログラムを書き、 struct Stateの定義をイベントハンドラ内で行っているのでしょうか? それでは無理です。 State型をテンプレート引数にしたいならStateをグローバルにする必要があります。 エラーメッセージは恐らくそのことを言っています。
その他の回答 (5)
- KoHal
- ベストアンサー率60% (110/181)
あなたが何をしようとしているのか漸く判りました。根本的に無茶なことをしようとしていますね(苦笑。 コンソールアプリのソースをそのままGUIアプリの、しかもイベントハンドラ内に貼り付けても動作する訳ないですよ。 No.5の補足に関しては、 「operator<<()の定義をイベントハンドラから出せ」 が回答ですが、しかしそれだけではあなたのそのプログラムは動作しないはずです。 あなたに必要なのは、「C++の入門書」と「BCBの入門書」の2つのようです。 BCBは非常に敷居の低い開発環境ですが、さすがにプログラミングの基本が判らない状態では使えません。 掲示板でのアドバイスも、「自分なりに勉強してある程度までは理解したが、ここが判らない」という人には有効ですが、何も判らない人にはアドバイスのしようがありません。 急がば回れと言うことわざがありますね。 プログラミングを身に付けたかったら、まずきちんとした入門書(薄いのは役に立ちません)を読むことから始めてください。
補足
そうなんです。ostreamに関してはBCBにもヘルプであったので、使えるのかと思っていたのですが… ありがとうございました。勉強し直します。
- KoHal
- ベストアンサー率60% (110/181)
ただ単にStateの定義を関数内から出せばよいのです。 using namespace std; struct State { //略 }; void __fastcall TForm3::Button1Click(TObject *Sender) { State s; //などなど } 実際的にはソースファイルを分割してしまう方が良いかと思いますが。
補足
おっしゃったとおりに, using namespace std; struct State { //メンバ変数の定義 //メンバ関数の定義 }; void __fastcall TForm3::Button1Click(TObject *Sender) { としたところ, void __fastcall TForm3::Button1Click(TObject *Sender) { // 状態を表示する static ostream & operator << ( ostream & ostr , const State & s ) { ostr << (s.wolf ? "" : "w") << (s.goat ? "" : "g") << (s.cabbage ? "" : "c") << (s.man ? "" : "m") << "-" << (s.wolf ? "w" : "") << (s.goat ? "g" : "") << (s.cabbage ? "c" : "") << (s.man ? "m" : ""); return( ostr ); } 上記の文に対し、 「宣言の型が多すぎる」 「ここでは型’State’は定義できない」 「'_fastcall TForm3::Button1Click(TObject *)'はTForm3のオブジェクトではない」 「ここには記憶クラスstaticは使用できない」 「宣言構文のエラー」と表示されました…。
- επιστημη(@episteme)
- ベストアンサー率46% (546/1184)
> どうしたらよいのでしょう… クラスの設計からやり直すのがbetterではないかと。 StateがStateの履歴(deque<State>)を持つのが妥当な設計とは思えません。 # staticメンバとして持つなら理解できますが。
お礼
お返事ありがとうございました。 理解に乏しいので、ヒントのようなものを頂けないでしょうか。
補足
DOSではコンパイルできるんですけどね… ありがとうございました…
- επιστημη(@episteme)
- ベストアンサー率46% (546/1184)
> s.path.push_back( *this ); > に対して > E2285 'deque<State *allocator<State*>>::push_back(const State)'に一致するものが見つからないと表示されてしまいます。。(涙 当然です。ポインタを要素とするように変更したのですから。
補足
初心者で理解に苦しいです…。 ありがとうございます。どうしたらよいのでしょう…
- επιστημη(@episteme)
- ベストアンサー率46% (546/1184)
dequeだと自分自身をメンバに含んでしまい、無限再帰に落ち込むのでしょう。 deque<State*> もしくは list<State> ではいかがでしょうか?
お礼
お返事ありがとうございます。 deque<State> pathをdeque<State*> pathに という意味合いで受け取りました。 すると、状態に対するオペレータの s.path.push_back( *this ); に対して E2285 'deque<State *allocator<State*>>::push_back(const State)'に一致するものが見つからないと表示されてしまいます。。(涙
補足
お返事ありがとうございます。おっしゃるとおりです。 こんな感じです↓ void __fastcall TForm3::Button1Click(TObject *Sender) { using namespace std; struct State { // // 状態を表すフラグ // false は、川の左岸、true は、川の右岸を表わす // bool wolf; bool goat; bool cabbage; bool man; ・ ・ ・ グローバルにする?参考書等で調べてみたのですが、理解に難しいです。