Error: expected type-specifier before 'ClassName'
Asked Answered
H

2

67
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))              );

I'm trying to understand why the above won't compile. For Whatever reason, when I try to create an instance of Rect2f (which DOES inherit from the Shape class specified the shared_ptr template argument, just like Circle), I get the following errors:

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

Everything about the Circle shared_ptr is perfectly fine. There are no problems with it; it's only the Rect2f which is causing issues.

Furthermore, the values passed into the constructor are valid.

So, what could the issue be with this one? I have Rect.h included for this. For brevity's sake (and incase I missed something in that file which may be affecting this), I'll post the following:

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;

};

Source of Error Function and File Header (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 Function Test (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();
}

Question

Judging from the errors provided, what am I missing here? Also, what can be done to rectify this issue?

Hereabouts answered 13/1, 2012 at 2:18 Comment(2)
Did you include the header for Rect2f ? Or did you do a forward declaration ?Leitmotif
Yes, I did include the header for Rect2f.Hereabouts
L
237

For future people struggling with a similar problem, the situation is that the compiler simply cannot find the type you are using (even if your Intelisense can find it).

This can be caused in many ways:

  • You forgot to #include the header that defines it.
  • Your inclusion guards (#ifndef BLAH_H) are defective (your #ifndef BLAH_H doesn't match your #define BALH_H due to a typo or copy+paste mistake).
  • Your inclusion guards are accidentally used twice (two separate files both using #define MYHEADER_H, even if they are in separate directories)
  • You forgot that you are using a template (eg. new Vector() should be new Vector<int>())
  • The compiler is thinking you meant one scope when really you meant another (For example, if you have NamespaceA::NamespaceB, AND a <global scope>::NamespaceB, if you are already within NamespaceA, it'll look in NamespaceA::NamespaceB and not bother checking <global scope>::NamespaceB) unless you explicitly access it.
  • You have a name clash (two entities with the same name, such as a class and an enum member).

To explicitly access something in the global namespace, prefix it with ::, as if the global namespace is a namespace with no name (e.g. ::MyType or ::MyNamespace::MyType).

Lazy answered 22/3, 2012 at 20:19 Comment(4)
Two exceptions.h in separate subdirectories; both #ifndef __ProjectName__exceptions_; one includes the other. D'oh!Beamy
This is why I installed clang for visual studio, so I can get better error messages when I'm stumped.Vestpocket
I had the same guard being used in both file.. Thanks, it helped.Dewy
A very similar situation can happen if 2 libraries include the same class. Recently while developing an Argument class I had the error come up unexpectently, and it turned out that 2 using namespace (one with an undocumented class of the same name) caused the error.Droughty
R
9

First of all, let's try to make your code a little simpler:

// 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());

Okay, so now we see that the parentheses are clearly balanced. What else could it be? Let's check the following code snippet's error:

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

This may seem like weird usage, and it is, but I really hate memory leaks. However, the output does seem useful:

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

Aha! Now we're just left with the error about the parentheses. I can't find what causes that; however, I think you are forgetting to include the file that defines Rect2f.

Ranch answered 13/1, 2012 at 2:33 Comment(9)
Ok, so Shape isn't found then?Hereabouts
No, Rect2f isn't found. You need to #include "Rect.h"Ranch
Here, I'll post the function (including the header) where that's coming from. One thing to note is that I already had #include "Rect.h"Hereabouts
Judging from the errors, I am pretty sure Rect2f is for some reason not being defined. Try to change #pragma once into an explicit include guard. What error does Rect2f r; at function scope in main give? Does a #warning in Rect.h ever get printed?Ranch
Ok, by include guard, I'm assuming the typical #ifndef #define #endif statement. Tried that, didn't change anything. And, as far as the main() error, this is what I get: error: expected ';' before 'rec'. Very weird indeed...Hereabouts
Note that the error I just posted for the function scope in main() should NOT be happening. I'll post the function in my question for clarity.Hereabouts
@Holland: Please show the code that gives that error. (This is probably too localised for StackOverflow and would be better asked on IRC (such as on ##c++-basic (with Qt references removed) or #qt on Freenode)).Ranch
let us continue this discussion in chatHereabouts
@Default: I've removed the link. I suspect the paste was simply the second code snippet in this answer, though.Ranch

© 2022 - 2024 — McMap. All rights reserved.