Ошибка: ожидаемый спецификатор типа перед 'ClassName'

shared_ptr<Shape> circle(new Circle(Vec2f(0, 0), 0.1, Vec3f(1, 0, 0)));

shared_ptr<Shape> rect(new Rect2f(Vec2f(0, 0), 5.0f, 5.0f, 0,
                                  Vec3f(1.0f, 1.0f, 0))              );

Я пытаюсь понять, почему вышеприведенное не скомпилируется. По какой-то причине, когда я пытаюсь создать экземпляр Rect2f (который ДЕЙСТВИТЕЛЬНО наследует от класса Shape, указанного аргументом шаблона shared_ptr, точно так же, как Circle), я получаю следующие ошибки:

error: expected type-specifier before 'Rect2f'
error: expected ')' before 'Rect2f'

Все в Circle shared_ptr прекрасно. С этим проблем нет; только Rect2f вызывает проблемы.

Кроме того, значения, переданные в конструктор, являются допустимыми.

Итак, в чем может быть проблема с этим? У меня есть Rect.h для этого. Для краткости (и если я пропустил что-то в этом файле, что может повлиять на это), я опубликую следующее:

Rect.h

#pragma once

#include <QGLWidget>
#include <GL/glext.h>
#include <cmath>
#include <QDebug>
#include "Shape.h"
#include "Vec3f.h"
#include "rand.h"

const int DEFAULT_SQUARE_WIDTH = 5;
const int DEFAULT_SQUARE_HEIGHT = 5;

typedef enum {
    RC_TOPLEFT,
    RC_TOPRIGHT,
    RC_BOTTOMRIGHT,
    RC_BOTTOMLEFT
} RectangleCorner;

class Rect2f : public Shape
{
public:

    Rect2f(
        Vec2f center = Vec2f(),
        float width = 4,
        float height = 4,
        float radius = 0,
        Vec3f color = Vec3f()
    );

    ~Rect2f();

    inline const float GetWidth( void ) const {
        return mWidth;
    }

    inline const float GetHeight( void ) const {
        return mHeight;
    }

    inline const Vec2f* GetCorner( RectangleCorner rc ) const {
        switch( rc ) {
        case RC_TOPLEFT:
            return mTopLeftCrnr;
            break;

        case RC_TOPRIGHT:
            return mTopRightCrnr;
            break;

        case RC_BOTTOMLEFT:
            return mBottomLeftCrnr;
            break;

        case RC_BOTTOMRIGHT:
            return mBottomRightCrnr;
            break;
        }
    }

    void UpdateCorners();

    virtual void Collide( Shape &s );

    virtual void Collide( Rect2f &r );

    virtual void Collide ( Circle &c );

    virtual bool Intersects( const Shape& s ) const;

    virtual bool Intersects( const Rect2f& s ) const;

    virtual bool IsAlive( void ) const;

    virtual float Mass( void ) const;

protected:

   virtual void Draw( void ) const;
   float mWidth, mHeight;
   Vec3f mColor;

private:
   Vec2f* mTopLeftCrnr;
   Vec2f* mTopRightCrnr;
   Vec2f* mBottomLeftCrnr;
   Vec2f* mBottomRightCrnr;

};

Функция источника ошибки и заголовок файла (mainwindow.cpp)

#include "ui_mainwindow.h"
#include "Vec2f.h"
#include "Rect2f.h"
#include "SharedPtr.h"

MainWindow::MainWindow(QWidget *parent) :
    QMainWindow(parent),
    ui(new Ui::MainWindow)
{
    ui->setupUi( this );

    BoxOfShapes* display = new  InteractiveBoxOfShapes( this, 600, 600 );
    ui->mGridLayout->addWidget( display );
    ui->mStatusBar->showMessage( "status ok" );

    QObject::connect( display, SIGNAL( numShapesChanged( int ) ), this, SLOT( setNumShapes(int) ) );
    QObject::connect( ui->mResetButton, SIGNAL( pressed() ), display, SLOT( resetWorld() ) );
    shared_ptr<Shape> circle(
                new Circle(
                    Vec2f( 0, 0 ),
                    0.1,
                    Vec3f( 1, 0, 0 ) ) );
    /*std::shared_ptr<Shape> rect( <---error
                     new Rect2f(
                        Vec2f( 0, 0 ),
                        5.0f,
                        5.0f,
                        0,
                        Vec3f( 1.0f, 1.0f, 0 )
                    )
                );*/
    shared_ptr< Shape > rect( new Rect2f() ); //error - second attempt 
    display->addShape( circle );
    display->addShape( rect );
}

Тест основной функции (main.cpp)

#include <QtGui/QApplication>
#include "mainwindow.h"
#include "Rect2f.h"

int main(int argc, char *argv[])
{
    Rect2f rec;

    QApplication a(argc, argv);
    MainWindow w;
    w.show();

    return a.exec();
}

Вопрос

Судя по приведенным ошибкам, что мне здесь не хватает? Кроме того, что можно сделать, чтобы исправить эту проблему?


person zeboidlund    schedule 13.01.2012    source источник
comment
Вы включили заголовок для Rect2f? Или вы сделали предварительную декларацию?   -  person J.N.    schedule 13.01.2012
comment
Да, я включил заголовок для Rect2f.   -  person zeboidlund    schedule 13.01.2012


Ответы (2)


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

Это может быть вызвано многими способами:

  • Вы забыли #include заголовок, который его определяет.
  • Ваша защита включения (#ifndef BLAH_H) неисправна (ваша #ifndef BLAH_H не соответствует вашей #define BALH_H из-за опечатки или ошибки копирования и вставки).
  • Ваши охранники включения случайно используются дважды (два отдельных файла, оба используют #define MYHEADER_H, даже если они находятся в разных каталогах)
  • Вы забыли, что используете шаблон (например, new Vector() должно быть new Vector<int>())
  • Компилятор думает, что вы имели в виду одну область видимости, когда на самом деле вы имели в виду другую (например, если у вас есть NamespaceA::NamespaceB и <global scope>::NamespaceB, если вы уже находитесь в пределах NamespaceA, он будет искать в NamespaceA::NamespaceB и не будет проверять <global scope>::NamespaceB), если вы явно не получите к нему доступ .
  • У вас конфликт имен (две сущности с одинаковыми именами, например класс и член перечисления).

Чтобы получить явный доступ к чему-либо в глобальном пространстве имен, добавьте к нему префикс ::, как если бы глобальное пространство имен является пространством имен без имени (например, ::MyType или ::MyNamespace::MyType).

person Jamin Grey    schedule 22.03.2012
comment
Два exceptions.h в отдельных подкаталогах; оба #ifndef __ProjectName__exceptions_; одно включает другое. О! - person OJFord; 19.03.2015
comment
Вот почему я установил clang для визуальной студии, чтобы я мог получать более качественные сообщения об ошибках, когда я в тупике. - person Dan; 18.11.2015
comment
У меня в обоих файлах использовалась одна и та же защита. Спасибо, это помогло. - person Yogesh Kumar Gupta; 07.12.2020
comment
Очень похожая ситуация может произойти, если 2 библиотеки включают один и тот же класс. Недавно при разработке класса Argument у меня неожиданно возникла ошибка, и оказалось, что 2 using namespace (один с недокументированным классом с таким же именем) вызвали ошибку. - person Oliver; 24.04.2021

Прежде всего, давайте попробуем сделать ваш код немного проще:

// No need to create a circle unless it is clearly necessary to
// demonstrate the problem

// Your Rect2f defines a default constructor, so let's use it for simplicity.
shared_ptr<Shape> rect(new Rect2f());

Итак, теперь мы видим, что скобки четко сбалансированы. Что еще это может быть? Давайте проверим следующий фрагмент кода:

int main() {
    delete new T();
}

Это может показаться странным использованием, и это так, но я действительно ненавижу утечки памяти. Тем не менее, вывод кажется полезным:

In function 'int main()':
Line 2: error: expected type-specifier before 'T'

Ага! Теперь мы просто остались с ошибкой о скобках. Я не могу найти причину этого; однако я думаю, что вы забыли включить файл, определяющий Rect2f.

person Anton Golov    schedule 13.01.2012
comment
Итак, Shape не найден? - person zeboidlund; 13.01.2012
comment
Нет, Rect2f не найдено. Вам нужно #include "Rect.h" - person Anton Golov; 13.01.2012
comment
Здесь я опубликую функцию (включая заголовок), откуда она исходит. Стоит отметить, что у меня уже было #include "Rect.h" - person zeboidlund; 13.01.2012
comment
Судя по ошибкам, я почти уверен, что Rect2f по какой-то причине не определено. Попробуйте изменить #pragma once на явную защиту включения. Какую ошибку выдает Rect2f r; в области действия функции в main? Печатается ли когда-нибудь #warning в Rect.h? - person Anton Golov; 13.01.2012
comment
Хорошо, под включением защиты я предполагаю типичный оператор #ifndef #define #endif. Пробовал так, ничего не изменилось. И что касается ошибки main(), вот что я получаю: error: expected ';' before 'rec'. Действительно очень странно... - person zeboidlund; 13.01.2012
comment
Обратите внимание, что ошибка, которую я только что опубликовал для области действия функции в main(), НЕ должна происходить. Я опубликую функцию в своем вопросе для ясности. - person zeboidlund; 13.01.2012
comment
@Holland: Пожалуйста, покажите код, который выдает эту ошибку. (Вероятно, это слишком локализовано для StackOverflow, и его лучше спросить в IRC (например, на ##c++-basic (с удаленными ссылками на Qt) или #qt на Freenode)). - person Anton Golov; 13.01.2012
comment
давайте продолжим обсуждение в чате - person zeboidlund; 13.01.2012
comment
@Default: я удалил ссылку. Я подозреваю, что вставка была просто вторым фрагментом кода в этом ответе. - person Anton Golov; 18.11.2015