开发者

How to have a Struct with template with a class

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.


$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();
}


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;
};


It looks like your struct is not defined when you declare the return type of getNewSValue.

With that you don't have that error:

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;
}

And you also have to qualify the SValue return type, because it is nested in CClass when you use it to define getNewSValue.


Declare SValue before getNewSValue():

template<class T> 
class CClass 
{ 
private: 
    typedef struct { 
        T *mValue; 
        T *next; 
        T *previous; 
        UInt16 index; 
    } SValue; 
public: 
    SValue* getNewSValue(void); 
}; 

Also, make sure UInt16 is defined.


how about trying this ? it worked on VS2008

template<class T>
class CClass
{
private:
    typedef struct {
        T *mValue;
        T *next;
        T *previous;
        __int16 index;
    } SValue;

public:
    SValue* getNewSValue(void)
    {
        return new SValue;
    }
};


The SValue-Type is inside the CClass-namespace. You need to fully qualify the typename outside the class.

template<typename T>
CClass<T>::SValue* CClass<T>::getNewSValue(void)

Also, you should make SValue public, if it is returned by a public method.


For the record, none of these will compile (on GCC 4.2 at least) as soon as a call to getNewSValue() is called. Since it's a public method that returns a pointer to a private type, you'll get a compile error stating that SValue is private.

In order for this to work, you'll either need to make SValue public, or change the type of the return value of getNewSValue() to something like void*, since it seems you're trying to make SValue an opaque type.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜