質問をすることでしか得られない、回答やアドバイスがある。

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

新規登録して質問してみよう
ただいま回答率
85.50%
Visual C++

Microsoft Visual C++はWindowsのCとC++の統合開発環境(IDE)であり、コンパイラやデバッガを含んでいます。

C++

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

Q&A

解決済

1回答

2748閲覧

【C++】未解決の外部シンボルというエラーを解決したい

ky_2

総合スコア5

Visual C++

Microsoft Visual C++はWindowsのCとC++の統合開発環境(IDE)であり、コンパイラやデバッガを含んでいます。

C++

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

0グッド

0クリップ

投稿2020/08/12 13:02

前提・実現したいこと

C++でコンソールで動く迷路ゲームを作成しています。とりあえず迷路生成と描画する関数はできたので動かしてみたのですが以下のエラーが発生しました。後述する方法でとりあえずエラーをなくすことはできたのですが、なぜこのエラーが発生するのかその原因を知りたいです。

発生している問題・エラーメッセージ

1>maze.cpp 1>maze.obj : error LNK2019: 未解決の外部シンボル "void __cdecl drawMaze(class std::vector<class std::vector<enum Object,class std::allocator<enum Object> >,class std::allocator<class std::vector<enum Object,class std::allocator<enum Object> > > > &)" (?drawMaze@@YAXAEAV?$vector@V?$vector@W4Object@@V?$allocator@W4Object@@@std@@@std@@V?$allocator@V?$vector@W4Object@@V?$allocator@W4Object@@@std@@@std@@@2@@std@@@Z) が関数 main で参照されました。 1> 定義済みの一致する可能性があるシンボルに関するヒント: 1> "void __cdecl drawMaze(class std::vector<class std::vector<enum Object,class std::allocator<enum Object> >,class std::allocator<class std::vector<enum Object,class std::allocator<enum Object> > > > const &)" (?drawMaze@@YAXAEBV?$vector@V?$vector@W4Object@@V?$allocator@W4Object@@@std@@@std@@V?$allocator@V?$vector@W4Object@@V?$allocator@W4Object@@@std@@@std@@@2@@std@@@Z) 1>C:\Users\USER\Documents\Visual Studio 2019\Projects\maze\x64\Debug\maze.exe : fatal error LNK1120: 1 件の未解決の外部参照 1>プロジェクト "maze.vcxproj" のビルドが終了しました -- 失敗。

該当のソースコード

C++

1#include<iostream> 2#include <random> 3 4using namespace std; 5 6//定数宣言 7//ステージの縦横は(棒倒し法の場合は)奇数である必要がある 8const int gStageWidth = 21; 9const int gStageHeight = 21; 10 11//迷路の状態 12enum Object { 13 OBJ_SPACE, //通路(空白で表現) 14 OBJ_WALL, //# 15 OBJ_START, //S 16 OBJ_GOAL, //G 17 OBJ_PLAYER, //P 18 OBJ_PLAYER_ON_START, //P 19 OBJ_PLATER_ON_GOAL, //P 20}; 21 22//関数プロトタイプ宣言群 23void genMaze(vector<vector<Object>>&); 24bool toWALL(vector<vector<Object>>&, int, int); 25void drawMaze(vector<vector<Object>>&); 26 27int main() { 28 vector<vector<Object>> state(gStageWidth, vector<Object>(gStageHeight)); 29 genMaze(state); 30 drawMaze(state); 31} 32 33//迷路生成アルゴリズム(棒倒し法) 34void genMaze(vector<vector<Object>> &state) { 35 //全てを通路にする 36 for (int x = 0; x < gStageWidth; x++) { 37 for (int y = 0; y < gStageHeight; y++) { 38 state[x][y] = OBJ_SPACE; 39 } 40 } 41 //上下の外壁の生成 42 for (int x = 0; x < gStageWidth; x++) { //フィールドの横幅の分だけループする。 43 state[x][0] = OBJ_WALL; 44 state[x][gStageHeight - 1] = OBJ_WALL; 45 } 46 47 //左右の外壁の生成 48 for (int y = 0; y < gStageHeight; y++) { 49 state[0][y] = OBJ_WALL; 50 state[gStageWidth - 1][y] = OBJ_WALL; 51 } 52 53 //内壁の生成 54 for (int i = 1; i < gStageWidth / 2; i++) { 55 for (int j = 1; j < gStageHeight / 2; j++) { 56 state[2 * i][2 * j] = OBJ_WALL; 57 } 58 } 59 60 //棒倒し法 61 for (int i = 1; i < gStageWidth / 2; i++) { 62 for (int j = 1; j < gStageHeight / 2; j++) { 63 while (true) { 64 //倒した先がSPACEでない限りループを回す. SPACEならWALLにする 65 if(toWALL(state, i, j)){ 66 break; 67 } 68 } 69 } 70 } 71} 72 73 74//ランダムで倒す方向を決定し、その方向がSPACEならWALLにする 75bool toWALL(vector<vector<Object>>&state, int x, int y) { 76 random_device rnd; 77 mt19937_64 mt(rnd()); 78 uniform_int_distribution<> rand_gen(1, 12); // 0からステージの大きさの範囲の一様乱数 79 int down_direction = rand_gen(mt) % 4; //倒す方向をランダムで決定(0: up, 1: down, 2: right, 3: left) 80 if (down_direction == 0) { 81 if (state[2 * x][2 * y - 1] == OBJ_SPACE) { 82 state[2 * x][2 * y - 1] = OBJ_WALL; 83 return true; 84 } 85 } 86 else if (down_direction == 1) { 87 if (state[2 * x][2 * y + 1] == OBJ_SPACE) { 88 state[2 * x][2 * y + 1] = OBJ_WALL; 89 return true; 90 } 91 } 92 else if (down_direction == 2) { 93 if (state[2 * x + 1][2 * y] == OBJ_SPACE) { 94 state[2 * x + 1][2 * y] = OBJ_WALL; 95 return true; 96 } 97 } 98 else if (down_direction == 3) { 99 if (state[2 * x - 1][2 * y] == OBJ_SPACE) { 100 state[2 * x - 1][2 * y] = OBJ_WALL; 101 return true; 102 } 103 } 104 return false; 105} 106 107//迷路描画 108void drawMaze(const vector<vector<Object>>&state) { 109 const char font[] = { ' ', '#', 'S', 'G', 'P', 'P', 'P' }; 110 for (int i = 0; i < gStageWidth; i++) { 111 for (int j = 0; j < gStageHeight; j++) { 112 Object o = state[i][j]; 113 cout << font[o]; 114 } 115 cout << endl; 116 } 117}

###試したこと
drawMaze関数のconstを外すと正常に描画されました。constは変数を変更できないようにするものだと認識しているのですが、なぜこれはだめなんでしょう?

環境

  • Visual Studio 2019 Enterprise

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

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

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

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

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

guest

回答1

0

ベストアンサー

仮引数に const が付いているかどうかで別の関数になるからです。 drawMaze のプロトタイプ宣言では仮引数に const が付いておらず、呼び出すときも const なしの関数があると思って呼び出します。 しかし、実際に存在する drawMaze の仮引数は const 付きですので、呼び出したい drawMaze が存在しない (未解決のシンボル) というエラーになります。

これの仮引数が参照ではなく実体であるならば const の有無は区別されません。 関数の内部だけの都合であって呼び出す側からは区別する意味がないからです。

cpp

1// これは通る 2int foo(int x); 3 4int main(void) { 5 foo(1); 6 return 0; 7} 8 9int foo(const int x) { 10 return x; 11}

cpp

1// これはエラーになる 2int foo(int& x); 3 4int main(void) { 5 int x = 1; 6 foo(x); 7 return 0; 8} 9 10int foo(const int& x) { 11 return x; 12}

投稿2020/08/12 13:24

SaitoAtsushi

総合スコア5437

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

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

ky_2

2020/08/12 13:32

理解できました。分かりやすいご回答を頂きありがとうございました。 おかげさまで無事実行できました。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.50%

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

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

質問する

関連した質問