Ошибка несоответствия значения типа с векторами

Я получаю следующее сообщение об ошибке, когда пытаюсь запустить свою программу:

 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) ===

И вот мой код для main, ведущей к строке, вызывающей ошибку:

#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 evilList; он компилируется, однако, если он есть, то этого не происходит при объявлении врага, подобного этому Enemy e(5);

он работает правильно

Обновления: если я изменю заголовок врага и 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

Он по-прежнему вылетает с той же ошибкой, это означает, что это должно быть что-то в main

ИСПРАВЛЕНИЕ: По какой-то причине, когда я объявляю это в строке над моими перечислениями, это работает, однако если ниже это не так, я понятия не имею, почему. Если кто-то может объяснить это, пожалуйста, продолжайте.


person Community    schedule 04.06.2013    source источник
comment
std::vector ‹Enemy› вражеский список;//здесь возникает ошибка   -  person    schedule 05.06.2013
comment
Можете ли вы свести это к минимальному тестовому сценарию, чтобы нам не приходилось пробираться через весь этот другой код?   -  person Oliver Charlesworth    schedule 05.06.2013
comment
Есть заголовок и конструктор для Enemy, есть оператор включения для main (#include include/Enemy.h) и объявление вектора объекта Enemy(std::vector ‹Enemy› вражеский список;//происходит ошибка здесь).   -  person    schedule 05.06.2013
comment
Не знаю. Все выглядит нормально. Я предполагаю, что происходит что-то еще, что вы не указали здесь, что вызывает проблему. Начните комментировать вещи в Enemy.h и посмотрите, сможете ли вы изолировать их таким образом. Возможно, попробуйте также объявить врага за пределами вектора и посмотрите, сработает ли это.   -  person Michael Dorgan    schedule 05.06.2013
comment
обратите внимание на исправление моего вопроса   -  person    schedule 06.06.2013


Ответы (2)


Чтобы иметь vector какого-либо типа значения, тип должен иметь доступный конструктор без аргументов, которого нет у вас (т.е. это то, о чем говорит вам сообщение об ошибке). Однако, поскольку я сомневаюсь, что вы хотите скопировать Enemys, вы должны хранить их по указателю, т.е.

vector<Enemy*> enemies;
for (int i = 0; i < NUM_ENEMIES; ++i)
    enemies.push_back(new Enemy(type));

ИЗМЕНИТЬ Я только что заметил, что у вас есть следующее объявление

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;
}

Так что это ваша проблема. Когда приходит время разрешить шаблон, компилятор видит значение перечисления (которое может быть параметром шаблона, как и любой другой целочисленный тип) и предполагает, что вы имели в виду именно его. Однако, поскольку ни один из векторных шаблонов не совпадает (все они имеют класс в качестве первого параметра шаблона), он не компилируется. Следовательно, ваша ошибка.

person Jacob    schedule 04.06.2013
comment
Это неправда. Для некоторых функций требуется только конструктивность по умолчанию. Кроме того, меня ужасает ваше отвратительное использование необработанных новинок. - person Puppy; 05.06.2013
comment
Это неправильно, и вы не должны использовать ключевое слово new таким образом. Не комментируйте некорректно то, о чем вы ничего не знаете. - person ; 05.06.2013
comment
@ user1814893: Учитывая, что не работает ваш код, такой ответ кажется несколько лицемерным... - person Oliver Charlesworth; 05.06.2013
comment
@Oli: Его критика new удивительно точна, учитывая ужасный код в OP. - person Puppy; 05.06.2013
comment
Использование new like that было сделано для того, чтобы сделать пример максимально кратким. Если бы я знал, что люди воспримут это так близко к сердцу, я бы написал по-другому. @DeadMG, у меня сложилось впечатление, что каждый метод класса шаблона должен скомпилироваться, чтобы он работал. Учитывая, что ваш ответ функционально эквивалентен, я не понимаю резкости вашей критики. - person Jacob; 05.06.2013
comment
Извините, после прочтения того, что я сказал, я понимаю, что получилось немного язвительно. Поверь мне, это не было моим намерением - person ; 06.06.2013
comment
@user1814893 user1814893 Я нашел вашу настоящую проблему, в немалой степени потому, что ваша искренность убедила меня получше взглянуть на ваш код. - person Jacob; 06.06.2013
comment
Большое спасибо, пока я уже исправил это я не знал причину. Это полезно знать для будущих знаний. - person ; 07.06.2013
comment
Проголосовал за отклонение отрицательного - ответ обновлен; предыдущие версии тоже были неплохи; Этот ответ был выбран в качестве ответа. Пользователи должны воздерживаться от нытья без качки. Если он не соответствует предпочтительному формату, но решает проблему, то вместо этого напишите комментарий или ответ. - person Elias ringhauge; 08.02.2016

Для некоторых функций std::vector<T> требуется, чтобы T была конструируемой по умолчанию. Ваш класс Enemy не может быть построен по умолчанию, поэтому компилятор выдает ошибку. Либо определите конструктор по умолчанию для Enemy, не вызывайте функции vector, требующие конструктивности по умолчанию, либо измените vector на другой тип.

Учитывая использование virtual в Enemy и то, что std::vector<Enemy> никогда не сможет принять производный класс, а также использование вами отвратительных глобальных переменных, массивов C и другого ужасного кода, я собираюсь утверждать, что вы понятия не имеете, что происходит.

std::vector<Enemy> может иметь только Enemy. Он не может содержать производный класс Enemy или что-то еще. Он может содержать только Enemy. Если вы хотите иметь vector вещей, которые могут быть различными производными классами, вы должны использовать указатель с определенной степенью владения. Это означает, что вы должны решить проблему того, кому принадлежат объекты, на которые указывают указатели, и, кроме того, вы должны понимать концепцию владения и то, какие интеллектуальные указатели доступны. Это необходимые знания для C++, и без них вы далеко не уйдете.

person Puppy    schedule 04.06.2013
comment
Он не содержит производного класса врага, враг не является суперклассом, это просто независимый самостоятельный класс. Врагу просто нужно хранить векторы путевых точек и тип (int). Что касается конструктивности по умолчанию, то почему я могу создавать векторы следующего Block::Block(int type, int X, int Y) или TextBlock::TextBlock(int X, int Y), вы можете видеть в сегментах, которые у меня есть создал векторы из них, и он отлично компилируется. - person ; 05.06.2013
comment
@user1814893 user1814893: Если это не суперкласс, то почему у него есть виртуальный деструктор? Они полезны только для суперклассов. В любом случае, вектор требует конструктивности по умолчанию только для некоторых функций (не для всех). Простое объявление вектора Enemy не должно быть незаконным. Вам нужно сократить свой код, чтобы удалить весь шум и только продемонстрировать проблему. - person Puppy; 05.06.2013
comment
именно так кодовые блоки настраивают деструкторы при создании класса, я этого не заметил, но в будущем изменю - person ; 06.06.2013