Вопрос:
При попытке запустить мою программу появляется следующее сообщение об ошибке:
main.cpp|44|error: type/value mismatch at argument 1 in template parameter list for ‘template<class _Tp, class _Alloc> class std::vector’ main.cpp|44|error: expected a type, got ‘(render)3u’ main.cpp|44|error: template argument 2 is invalid main.cpp|44|error: invalid type in declaration before ‘;’ token === Build finished: 4 errors, 0 warnings (0 minutes, 0 seconds) ===
И вот мой код для основного, ведущего к строке, вызывающей ошибку:
#include<stdlib.h> #include<windows.h> #include<GL/glut.h> #include<GL/freeglut.h> #include<iostream> #include <vector> #include «include/Block.h» #include <string> #include <sstream> #include «include/TextBlock.h» #include «include/Enemy.h» string text; stringstream ss; enum render {Normal,SelectRangeText,SelectSText,Enemy,EnemyTypeSelection}; enum render state; enum type { Foreground, Background, Midground }; enum type selected; enum types { Blocks, Enemies, Text }; enum types special; string names[4] = { «grass» , «smallGrassBlock» , «dirt» , «sand» }; void createEnemy(int,int); void addEnemyWaypoint(int,int); void addToList(vector<Block> &list,int x,int y); void placeText(int x,int y); void initTextures(); GLint GetTexture(string file); void IdleFunction(); void removeBlock(int x,int y); int xOffset,yOffset,multiuse = 0; using namespace std; string to_string(int number); void placeBlock(int x,int y); void drawBitmapText(char *string, float x, float y, float z); void reshape(int w, int h); void render(void); void keyboard(unsigned char c,int x,int y); void mouse(int button,int state, int x, int y); void arrows(int key, int x, int y ); std::vector <Block> backBlockList; std::vector <TextBlock> textBlockList; std::vector <Block> midBlockList; std::vector <Block> foreBlockList; std::vector <Enemy> enemyList;//error occurs here GLuint textures[1]; unsigned int screenXSize=800; unsigned int screenYSize=800; unsigned int selectedBlockType = 1; int main(int argc, char ** argv) {
Заголовок для врага:
#ifndef ENEMY_H #define ENEMY_H #include<GL/freeglut.h> #include <vector> class Enemy { public: Enemy(int Type ); virtual ~Enemy(); void render(int,int,GLuint); void addWaypoint(int,int); protected: private: int type; std::vector <int> X, Y; int xsize,ysize; }; #endif // ENEMY_H
И конструктор для врага:
Enemy::Enemy(int Type) { xsize=30; ysize=30; type=Type; }
Однако он будет работать корректно, если я подстановлю тип моего вектора в int. Когда прокомментирована следующая строка: std :: vector enemyList; он компилируется, однако, если он там не делает этого, когда объявляет врага подобным Enemy e (5);
он работает правильно
Обновления: если я изменяю заголовок врага и cpp на что-то вроде следующего:
CPP:
#include «../include/Enemy.h» Enemy::Enemy( ) { } Enemy::~Enemy() { //dtor }
заголовок
#ifndef ENEMY_H #define ENEMY_H class Enemy { public: Enemy( ); ~Enemy(); protected: private: }; #endif // ENEMY_H
Он по-прежнему падает с той же ошибкой, это означает, что это должно быть что-то в основном
ИСПРАВЛЕНИЕ: По какой-то причине, когда я объявляю это в строке над моими перечислениями, это работает, однако, если ниже этого нет, я понятия не имею, почему. Если кто-то может это объяснить, пожалуйста, продолжайте.
Лучший ответ:
Чтобы иметь vector некоторого типа значения, тип должен иметь доступный конструктор без аргументов, который у вас нет (т.е. То, что сообщает сообщение об ошибке). Однако, поскольку я сомневаюсь, что вы хотите скопировать вокруг Enemy s, вы должны хранить их указателем, т.е.
vector<Enemy*> enemies; for (int i = 0; i < NUM_ENEMIES; ++i) enemies.push_back(new Enemy(type));
EDIT Я просто заметил, что у вас есть следующая декларация
class Enemy…
но вы также объявляете значение перечисления
enum render {… ,Enemy, ….
Я просто скомпилировал следующий код и получил подозрительно подобную ошибку:
#inlcude <vector> class A {}; enum type {A, B, C}; std::vector<A> As; int main(int argc, char** argv) { return 0; }
Так вот ваша проблема. Когда придет время для решения шаблона, компилятор видит значение перечисления (которое может быть параметром шаблона, как и любой другой интегральный тип), и предполагает, что тот, который вы имели в виду. Однако, поскольку ни один шаблон шаблона не совпадает (все они имеют класс в качестве первого параметра шаблона), он не компилируется. Следовательно, ваша ошибка.
Ответ №1
Для некоторых функций std::vector<T> требует, чтобы T был конструктивным по умолчанию. Класс Enemy не может быть сконфигурирован по умолчанию, поэтому компилятор выдает ошибку. Определите конструктор по умолчанию для Enemy, не вызывайте vector функции, которые требуют стандартной конструктивности, или изменяйте vector другого типа.
Учитывая virtual использование в Enemy и что std::vector<Enemy> никогда не сможет принять производный класс, а также использовать отвратительные глобальные переменные, массивы C и иначе ужасный код, я собираюсь утверждать, что вы не представляете, что такое продолжается.
std::vector<Enemy> может только удерживать Enemy. Он не может содержать производный класс Enemy или что-то еще. Он может удерживать Enemy. Если вы хотите иметь vector вещей, которые могут быть различными производными классами, вы должны использовать указатель некоторой степени владения. Это означает, что вы должны решить проблему того, кому принадлежат объекты, на которые указывают, и, кроме того, вы должны понимать концепцию собственности и какие интеллектуальные указатели доступны. Это важное знание для C++, и вы не обойдетесь без него.