🎄teratailクリスマスプレゼントキャンペーン2024🎄』開催中!

\teratail特別グッズやAmazonギフトカード最大2,000円分が当たる!/

詳細はこちら
C++

C++はC言語をもとにしてつくられた最もよく使われるマルチパラダイムプログラミング言語の1つです。オブジェクト指向、ジェネリック、命令型など広く対応しており、多目的に使用されています。

Q&A

解決済

1回答

3771閲覧

構造体が未定義と表示される原因と対処法が知りたい。

退会済みユーザー

退会済みユーザー

総合スコア0

C++

C++はC言語をもとにしてつくられた最もよく使われるマルチパラダイムプログラミング言語の1つです。オブジェクト指向、ジェネリック、命令型など広く対応しており、多目的に使用されています。

0グッド

0クリップ

投稿2021/01/29 05:54

編集2021/01/29 08:04

提示コードのコメント部で囲ってあるコードですがなぜ以下のエラーが発生するのでしょうか? エラーが4件起きているのですが何が悪いのか理解出来ません。

エラー1「 "std::array<std::array<Stage::MapChip, 10Ui64>, 10Ui64>" から "std::array<std::array<MapChip, 10Ui64>, 10Ui64>" への適切なユーザー定義変換が存在しません 」

エラー2「 'Stage::getMap': 再定義されています。異なる基本型です。 」

エラー3「 'std::array<std::array<MapChip,10>,10> Stage::getMap(void)': オーバーロード関数は、'std::array<std::arrayStage::MapChip,10,10> Stage::getMap(void)' と戻り値の型のみが異なります。 」

エラー4「 宣言に "std::array<std::array<Stage::MapChip, 10Ui64>, 10Ui64> Stage::getMap()" 」

cpp

1#ifndef ___STAGE_HPP_ 2#define ___STAGE_HPP_ 3 4#include "../Actor_2D.hpp" 5#include "Block.hpp" 6#include "../Game.hpp" 7 8#include <vector> 9#include <array> 10#include <iostream> 11#include <algorithm> 12 13// 前方宣言 14 15class Stage : public Actor_2D 16{ 17public: 18 19 20 21 Stage(class Game* g, const char* fileName); //コンストラクタ 22 ~Stage(); //デストラクタ 23 24 void Update() override; //更新 25 void Draw() override; //描画更新 26 27 28 // 描画UV座標 29 typedef struct DrawUV 30 { 31 glm::vec2 start; //ここから 32 glm::vec2 end; //ここまで 33 34 }DrawUV; 35 36 // マップチップの種別 37 typedef enum MapChipType 38 { 39 Block, //破壊 可能 40 notBreak_Block, //破壊 不可 41 Item, //アイテム 42 43 Invalid, //無効 44 } MapChipType; 45 46 47 // マップチップの情報 48 typedef struct MapChip 49 { 50 MapChipType type; //種類 51 glm::vec2 mPosition; //座標 52 DrawUV UV; //描画範囲 53 }MapChip; 54//////////////////////////////////////////////////////////////////////////////////////// 55 std::array< std::array<MapChip, 10>, 10> getMap(); //マップセル取得 56/////////////////////////////////////////////////////////////////////////////////////// 57private: 58 59 std::shared_ptr<Sprite> mSprite; //スプライトクラス 60 61 std::array< std::array<MapChip,10>,10> mMap; //マップデータ 62 63 glm::vec2 blockUV; //ブロックのUV座標 64 glm::vec2 notBreak_blockUV; //固定ブロックのUV座標 65}; 66 67#endif; 68

cpp

1#include "../../Header/Game/Stage.hpp" 2#include "../../Header/Actor_2D.hpp" 3 4#include "../../Header/Game.hpp" 5 6#include <vector> 7#include <array> 8#include <iostream> 9#include <algorithm> 10 11 12struct MapChip; 13 14// コンストラクタ 15Stage::Stage(class Game* g, const char* fileName) : Actor_2D() 16{ 17 Owner = g; // Game クラス 18 mSprite = std::make_shared<Sprite>(Owner,fileName); //スプライトクラス 19 20 21 22 23 24 // マップ配列を初期化 25 MapChip m{ 26 MapChipType::Invalid, //マップの種類 27 glm::vec2(0,0), //座標 28 DrawUV{ glm::vec2(0,0),glm::vec2(0,0)} //描画UV座標 29 }; 30 31 32 for (int i = 0; i < mMap.size(); i++){ 33 std::fill(mMap.at(i).begin(), mMap.at(i).end(), m); 34 } 35 36 //画面の左上 37 const int width = -(int)(SCREEN_WIDTH / 2); // 38 const int height = (int)(SCREEN_HEIGHT / 2); // 39 40 // 座標を設定 41 for (int y = 0; y < mMap.size(); y++) 42 { 43 for (int x = 0; x < mMap.at(y).size(); x++) 44 { 45 // 46 mMap.at(y).at(x).mPosition.x = (float) (width + (CELL * x)); 47 mMap.at(y).at(x).mPosition.y = (float) (height - (CELL * y)); 48 49 mMap.at(y).at(x).type = MapChipType::Block; // 50 51 // 52 mMap.at(y).at(x).UV.start = glm::vec2(0, 0); 53 mMap.at(y).at(x).UV.start = glm::vec2(CELL, CELL); 54 55 } 56 } 57 58} 59 60// 描画 61void Stage::Draw() 62{ 63 for (int y = 0; y < mMap.size(); y++) 64 { 65 for (int x = 0; x < mMap.at(y).size(); x++) 66 { 67 68 69 mSprite->DrawGraph(mMap.at(y).at(x).mPosition, mMap.at(y).at(x).UV.start, mMap.at(y).at(x).UV.end); 70 } 71 } 72 73} 74////////////////////////////////////////////////////////////////////////////////// 75std::array< std::array<MapChip, 10>, 10> Stage::getMap() 76{ 77 return mMap; 78} 79////////////////////////////////////////////////////////////////////////////////// 80 81// 更新 82void Stage::Update() 83{ 84 85} 86 87 88 89// デストラクタ 90Stage::~Stage() 91{ 92 93}

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

yumetodo

2021/01/29 06:04

それでできてるのでは????
int32_t

2021/01/29 06:08

何かエラーが出ているのでしょうか?
退会済みユーザー

退会済みユーザー

2021/01/29 06:23

文章を変更しました。
int32_t

2021/01/29 06:30

std::array に入れたいのはStageクラスの外のMapChip型ですか? それとも private な Stage::MapChip ですか?
退会済みユーザー

退会済みユーザー

2021/01/29 06:32

privateのMapChipです。
退会済みユーザー

退会済みユーザー

2021/01/29 08:04

質問内容を編集しました。
guest

回答1

0

ベストアンサー

しっかり前方宣言されているはずですが

前方宣言が間違っています。class Stage の定義の中で前方宣言してください。
また、Stage::getMap() の実装のほうの戻り値の型は、MapChipではなくStaget::MapChipと書く必要があります。

さらに、private な型を public なメソッドで返そうとしているので、けっきょく Stage::MapChip の定義を public セクションに移動する必要があります。


一般論で public な内部 class/struct はメリットがほとんどありません。上記変更点はすべてなしにして、Stage::MapChipStage から追い出してトップレベルに移してしまったほうがコードはシンプルかもしれません。

投稿2021/01/29 06:37

編集2021/01/29 08:04
int32_t

総合スコア21679

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

退会済みユーザー

退会済みユーザー

2021/01/29 07:13

質問ですが前方宣言はclass Stageでやってくださいとありますが。クラス内のどこでやるべきなのでしょうか?
int32_t

2021/01/29 07:16

publicセクションの中でgetMap()の宣言より上ならどこでもよいですよ。
退会済みユーザー

退会済みユーザー

2021/01/29 07:21

'std::array<std::array<MapChip,10>,10> Stage::getMap(void)': オーバーロード関数は、'std::array<std::array<Stage::MapChip,10>,10> Stage::getMap(void)' と戻り値の型のみが異なります。 というエラーが出るのですがこれはなぜでしょうか? また再定義されましたというエラーも出るのですが 再定義してません。
int32_t

2021/01/29 07:24

グローバルな ::MapChip の宣言がどこかに残っているのでは?
退会済みユーザー

退会済みユーザー

2021/01/29 07:32 編集

治りません。また "std::array<std::array<Stage::MapChip, 10Ui64>, 10Ui64>" から "std::array<std::array<MapChip, 10Ui64>, 10Ui64>" への適切なユーザー定義変換が存在しません といったエラーも出るのですがどうすればいいのでしょういか?
fana

2021/01/29 07:34

getMap()の実装の戻り値記述がまちがってるんじゃないの? > std::array< std::array<MapChip, 10>, 10> Stage::getMap() 戻り値は, Stage::MapChip 型のarrayのarrayでしょ.
int32_t

2021/01/29 07:36 編集

class Stage { ... }; の外側の MapChip の宣言がどこかに残っていると、そういう再定義のエラーを引き起こします。たとえば提示されているコードだけでも余計な宣言が2つありますよね。
int32_t

2021/01/29 07:37

もう面倒くさいから Stage::MapChip の定義全部を Stage の外側に移動したらいいんじゃないですかね。public な inner class とかほとんどメリットがないので。
fana

2021/01/29 07:41

(そんなこと言い出したら,そもそも Stage::MapChip なんていう,いかにもStageの内部実装用の型を外部にgetさせるのかよ? っていう.)
fana

2021/01/29 07:46

typedef struct MapChip MapChip; //ゴミ class Stage { public: struct MapChip; //前方宣言 std::array< std::array<MapChip,10>, 10> getMap(); struct MapChip{}; private: std::array< std::array<MapChip,10>, 10> mMap; }; std::array< std::array< Stage::MapChip,10>, 10> Stage::getMap(){ return mMap; }
fana

2021/01/29 07:48

前方宣言の意味もわからんが,このくらいでコンパイル通るっしょ. 一番上の「ゴミ」は要らんが,残ってても影響はない.
fana

2021/01/29 07:54

この状態で,getMap()の実装の戻り値部分を前述のように,Stage::MapChip じゃなくて MapChip にしてしまうと, 「宣言と互換性がない」,「戻り値だけ異なる」,「ユーザ定義の変換もないし」 というエラーが出る. さらに,「ゴミ」が無い場合は,「そもそも MapChip ってなんですかね?」というエラーも出る.
退会済みユーザー

退会済みユーザー

2021/01/29 08:05

質問内容を編集しました。
int32_t

2021/01/29 08:05

コメントを回答に反映しました。
退会済みユーザー

退会済みユーザー

2021/01/29 08:06

std::array< std::array<Stage::MapChip, 10>, 10> Stage::getMap() としました。 Stage::MapChipとすることでエラーが治りました。
退会済みユーザー

退会済みユーザー

2021/01/29 08:08

質問ですがつまりクラスの外にclas struct を移動したほうがよくて クラス内に書かなほうがいいというこでしょうか?
int32_t

2021/01/29 08:09

更新された質問内のコードでも、余計な「struct MapChip;」がまだありますよ。ファイル名はわかりませんが、stage.cpp でしょうか。
退会済みユーザー

退会済みユーザー

2021/01/29 08:19

あっ消し忘れです。w
int32_t

2021/01/29 08:22

こういうトラブルに自力で対処できないなら、内部class/structは使わないほうが生産的です。
退会済みユーザー

退会済みユーザー

2021/01/29 10:38 編集

内部class/structは実際はどうやってやるのでしょうか?
int32_t

2021/01/29 12:14

現在のコードのMapChipが、内部structです。
退会済みユーザー

退会済みユーザー

2021/01/29 13:04

内部クラス、構造体はどういった場面で便利なのでしょうか?
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.36%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問