0

so I wrote a class and one of the functions returns a struct, both function and struct are contained within the class's private section. It's something similar to this:

template <typename T>
class myClass {
private:
    struct myStruct {
        ...
        T item;
        ...
    };

    myStruct* func(myStruct*, myStruct*);

public:
    ....
};

template <typename T>
inline myClass<T>::myStruct* func(myStruct* a, myStruct* b) {
...
};

When I try to test run the code, however, it warns me:

C2061   syntax error: identifier 'myStruct'
C2143   syntax error: missing ';' before '{'
C2447   '{': missing function header (old-style formal list?)

I've tried moving the function into the public area but it didn't help. I also tried to add "myClass::" before every "myStruct" in the parameters but the warnings still remain. Does it have something to do with the struct being inside of the class? Can someone help me, please?

Hao Lieu
  • 3
  • 1

3 Answers3

1

You need to qualify the name of the class and because the return type is a dependent name it needs a typename (you don't need inline though, methods of class templates are implicitly inline):

template <typename T>
typename myClass<T>::myStruct* myClass<T>::func(myStruct* a, myStruct* b) {

};

A struct is a class. struct is just an alternative keyword to declare a class. Only difference is default access. Also declaring the struct in the private section is not as private as you might expect. When there is a public method that returns a myStruct then from outside one can decltype(x.public_method()) to get the type even though the type is defined in the private section (actually similar is possible when there is a public method taking a parameter of type myStruct).

463035818_is_not_an_ai
  • 109,796
  • 11
  • 89
  • 185
1

You have two problems. One is covered by Where and why do I have to put the “template” and “typename” keywords? (and the answer from 463035818_is_not_a_number)

The other is that with

template <typename T>
inline myClass<T>::myStruct* func(myStruct* a, myStruct* b) {
...
};

you declare and define func as a non-member function. It's a global function.

You need to prefix the class name when defining member functions:

template <typename T>
inline typename myClass<T>::myStruct* myClass<T>::func(myStruct* a, myStruct* b) {
//                                    ^^^^^^^^^^^^
//                    Class name prefix added here
...
};
Some programmer dude
  • 400,186
  • 35
  • 402
  • 621
0

You need to prefix every instance of myStruct in the function definition with typename myClass<T>:: such that every mention of myStruct looks like typename myClass<T>::myStruct. The typename is required to tell the compiler that myStruct is a type and not a class member.

template <typename T>
inline typename myClass<T>::myStruct* myClass<T>::func(typename myClass<T>::myStruct* a, typename myClass<T>::myStruct* b) {
    ...
};

Edit: As @Some programmer dude mentioned, func must actually be qualified as a member of myClass. Also, the parameters is not required to be prefixed with typename myClass<T>:: but it doesn't hurt either.

Mestkon
  • 3,532
  • 7
  • 18
  • When the compiler parses the argument list we're already in the scope of the `myClass` class, so `myStruct` doesn't need a scope prefix and it's no longer a dependent name. – Some programmer dude Jul 15 '21 at 11:12