How to have a Struct with template with a class
Solution 1
$9.2/2- The key is the below quote from the C++ Standard03
`A class is considered a completely-defined object type (3.9) (or complete type) at the closing } of the class-specifier. Within the class member-specification, the class is regarded as complete within function bodies, default arguments and constructor ctor-initializers (including such things in nested classes). Otherwise it is regarded as incomplete within its own class member-specification.
Don't know what is UINT16
, but the following should work
template<class T>
class CClass
{
private:
typedef struct {
T *mValue;
T *next;
T *previous;
short int index; // Replacing with int for illustration only
} SValue;
public:
SValue* getNewSValue(void);
private:
};
EDIT 3: The ***
came there trying to make the change BOLD (which I should have deleted anyways)
template<class T> typename CClass<T>::SValue* CClass<T>::getNewSValue(void)
{
return new SValue;
}
int main(){
CClass<int> s;
s.getNewSValue();
}
Solution 2
Since the member function definition is in global scope, you need to qualify its return type with CClass::
to refer to the name within class scope. Also, the typename
keyword is needed when referring to typenames nested within templates.
template<typename T>
typename CClass<T>::SValue* CClass<T>::getNewSValue(void)
Also, the nested struct is unnamed. Note that in C++, classes and structs have proper names, and a typedef name is not a class name. You will be much better off avoiding the typedef.
struct SValue {
T *mValue;
T *next;
T *previous;
UInt16 index;
};
okami
Updated on June 30, 2022Comments
-
okami almost 2 years
With this code (just a class of test):
typedef unsigned short UInt16; template<class T> class CClass { public: SValue* getNewSValue(void); private: typedef struct { T *mValue; T *next; T *previous; UInt16 index; } SValue; }; template<typename T> SValue* CClass<T>::getNewSValue(void) { return new SValue; }
I have the following errors:
error C2143: syntax error : missing ';' before '*'
error C4430: missing type specifier - int assumed. Note: C++ does not support default-int
Is it possible to use a Struct within a class? If I declare the struct out of the class the template doesn't see the template
T
. -
Cedric H. over 13 yearsWhat is the purpose of the
typename
keywork in the definition ofgetNewSValue
? That's because SValue is unnamed and we have to refer to it using thetypedef
name ? -
Johannes Schaub - litb over 13 years@Cedric if we would omit
typename
, it would be parsed like the definition of a member calledSValue
of classCClass<T>
, for which no type was specified:tempate<class T> Class<T>::SValue;
. The tokens following would be junk and rejected by the compiler as syntax errors. This all is because the compiler by default assumes non-types if it can't lookup a name at parse time (i.e it doesn't know whatT
is yet, so it can't lookupSValue
). If you puttypename
,SValue
is correctly regarded as a typename for the membergetNewSValue
. -
okami over 13 yearsThe code you put generates the following error: "error C2244: 'CClass<T>::getNewSValue' : unable to match function definition to an existing declaration"
-
okami over 13 yearsThis is very verbose :-), But Potatos your code generates the following err, on the line: typename CClass<T>::SValue* CClass<T>::getNewSValue(void) ERROR ---> "error C2899: typename cannot be used outside a template declaration"
-
Potatoswatter over 13 years@okami: keep the
template< typename T >
part. For less verbose syntax, define the function inside theclass {}
scope. Thentypename
and qualification (on class-local types) aren't needed. -
mukeshkumar over 13 yearsfor a while you confused me with the triple pointers (*'s). I think it should be SValue* and not SValue***
-
Chubsdad over 13 years@hype: Yes, it is my fault. I was trying to make it BOLD and then decided not to do it. So I manually removed the leading ** but forgot the trailing ones :( Have edited my post accordingly
-
daohu527 about 3 yearsCan it be achieved by "decltype" now?