简体   繁体   中英

C++ Struct and “error: ISO C++ forbids declaration of '…' with no type”

I am trying to write classes and structs in C++, for example:

using namespace std;

struct Position { 
    int x; 
    int y;  
};

class Maze {
    Position pos;
    pos.x = 0;
    pos.y = 0;
};

int main() {
    return 0;
}

but it rises some errors when I try to compile it:

(gcc version 4.3.2)

10: error: ISO C++ forbids declaration of 'pos' with no type
10: error: expected ';' before '.' token
11: error: ISO C++ forbids declaration of 'pos' with no type
11: error: expected ';' before '.' token

It looks like this piece of code is pretty much the same as it in C++ Tutorial: Struct .

Answers to some other posts about "error: ISO C++ forbids declaration of '...' with no type" (such as this ) suggest to add namespace, but I find it hard see what is the reason why it does not work here.

In summary, I have the following questions:

  1. What does this error actually mean in this case?
  2. What does this error mean in general?
  3. Why this code does not work?
  4. How to make it work?

I will be grateful if someone could give an answer, and/or a direction of research/reading.

This code

pos.x = 0;
pos.y = 0;

needs to go in a function. One way would be to put it in the constructor, something like:

class Maze {
    Position pos;
public:
    Maze() {
        pos.x = 0;
        pos.y = 0;
    }
};

Note that I made the constructor public as otherwise you wouldn't be able to use the Maze class

Edit: Actually answering your questions:

What does this error actually mean in this case? The compiler doesn't know what to do with pos.x = 0 as it is expecting declarations at this point, not code.

What does this error mean in general? It usually means that the compiler doesn't know how to process the declaration you wrote.

Why this code does not work? Because you put executable code where declarations are supposed to go.

How to make it work? See the code above.

Since this question is titled "ISO C++ forbids declaration of “something” with no type", here's a more generic answer. C++ is unable to find the type, so just specify the type.

In my case, I was able to solve it only after adding a forward declaration.

A.hpp

class A
{
};

B.hpp

#include "A.hpp"
class B
{
public:
  A* inst;
};

This caused the error of ISO C++ forbids declaration of A with no type.

So I made a change in B.hpp as such:

#include "A.hpp"
class A;//the forward declaration
class B
{
public:
  A* inst;
};

and it compiled fine!

For a start, you cannot initialise the members at the top level of the class:

class Maze {
    Position pos;
    pos.x = 0;
    pos.y = 0;
};

You have to provide a constructor of some sort and, if you're after a default state for the position, that's probably where you want the initialisation done. Objects should generally be responsible for their own initialisation and tear-down:

using namespace std;

struct Position {
    int x;
    int y;
    Position() : x(0), y(0) {}
};

class Maze {
    Position pos;
};

int main () {
    return 0;
}

Lines 10 and 11 are

pos.x = 0;
pos.y = 0;

The compiler is assuming that you wanted to declare variables named 'pos.x' and 'pos.y', and is complaining because you haven't told it what type those variables are.

What want to do is to move those two assignments inside a constructor, just as The Dark suggests.

However, if I wasn't sure how complex things might get later on, I might write it this way:

class Position {
  private:
    int x;
    int y;
  public:
    Position(int x0, int y0) : x(x0), y(y0) {
        // Any other initialization here.
    }
    inline int getX() { return x; }
    inline int getY() { return y; }
    inline void setX(int x0) { x = x0; }
    inline void setY(int y0) { y = y0; }
}

class Maze : public Position {
    Maze() : Position(0,0) {
        // Any other initialization here.
    }
}

Some may say that this is overkill. It may well be, I don't know how complex your final problem really is. If you don't know for sure either, going with a class is probably safest.

The whole point to classes is data encapsulation. Don't expose anything you don't have to, and that way you don't have to worry about some other code changing values in ways you didn't expect. Using a struct may be sufficient, but if it isn't, going back and converting from a struct to a class may be more difficult than just going ahead with a class now.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM