13

My goal is a class like:

class UserInformation
{
public:
    userInfo getInfo(int userId);
private:
    struct userInfo
    {
        int repu, quesCount, ansCount;
    };
    userInfo infoStruct;
    int date;
};

userInfo UserInformation::getInfo(int userId)
{
    infoStruct.repu = 1000; 
    return infoStruct;
}

but the compiler gives error that in defintion of the public function getInfo(int) the return type userInfo is not a type name.

matthias krull
  • 4,389
  • 3
  • 34
  • 54
yolo
  • 2,757
  • 6
  • 36
  • 65

4 Answers4

17

It makes sense to make the nested structure type public, since the user code should be able to use it. Also, place the declaration of the structure before the point of its first use. Outside the class scope use scope resolution :: to refer to nested types.

class UserInformation
{
public:
    struct UserInfo
    {
        int repu, quesCount, ansCount;
    };


public:
    UserInfo getInfo(int userId);

private:
    UserInfo infoStruct;
    int date;
};

UserInformation::UserInfo UserInformation::getInfo(int userId)
{
    infoStruct.repu = 1000;
    return infoStruct;
}
pic11
  • 14,267
  • 21
  • 83
  • 119
6

If the member function is public, then the return type must be publicly visible! Therefore, move the inner struct definition into the public section.

Note also that it must be defined before the function that uses it.

Oliver Charlesworth
  • 267,707
  • 33
  • 569
  • 680
5

Just do UserInformation::userInfo UserInformation::getInfo(int userId).

Also, you should declare userInfo public.

Alexander Gessler
  • 45,603
  • 7
  • 82
  • 122
  • Why do we need the qualifier `UserInfomation` for `userInfo. Shouldn't the compiler by default check in the namescope of `UserInformation`? – anaken78 Dec 12 '16 at 23:54
  • @anaken78 What you, me, or anyone else thinks a compliant compiler _should_ do is irrelevant. This is what it **does** do. The class is not in scope until the function's argument list opens, so names in there cannot be looked up unqualified. I'm sure the reasoning behind this, in terms of parsing & whatnot, has been discussed at length elsewhere, if you want to search for it. Or just use a trailing return type: `auto UserInformation::getInfo(int userId) -> userInfo` (btw, these are some bad naming choices). The class & its members are in scope when the return type is declared in that position. – underscore_d May 26 '17 at 17:59
  • @underscore_d The question is not about what anyone *thinks* the compiler should do but what it should *actually* do. To clarify, the question "shouldn't the compiler XXX?" is a question as to how the compiler is supposed to behave, (how it does behave is different, but both are important), not an argument that the compiler is broken because it does not behave as one thinks. – Kröw Jan 27 '23 at 11:10
4

You need to change the order of the members of UserInformation and put struct UserInfo above the declaration of getInfo. The compiler complains that it can't work out the signature for getInfo because it hasn't seen the definition of its return type yet.

Also, if you are returning a struct from the function the type of the struct must be visible to the callers. So you need to make the struct public as well.

Jon
  • 428,835
  • 81
  • 738
  • 806