简体   繁体   中英

Template class with “typename”

I have a template class where I want to use objects of that class (along with the parameterized type) inside a map. So far this is the solution that I've been able to arrive at:

class IStatMsg;

template <typename T>
class ITier
{
public:

    // Methods
    ITier(TierType oType) : o_Type(oType){};
    virtual ~ITier(){};

    typename ITier<T> ParamITier;  // line 60

    ITier* Get(T oKey)
    {
        std::map<T, ParamITier*>::iterator it = map_Tiers.find(oKey);   // line 64

        if (it != map_Tiers.end())
            return it->second;

        return NULL;
    }

    void Set(T oKey, ITier* pTier)
    {
        map_Tiers.insert(pair<T, ParamITier*>(oKey, pTier)); // line 74
    }

    TierType GetType() { return o_Type; }

protected:
    // Methods

    // Attributes
    std::map<T, ParamITier*> map_Tiers;  // line 83
    TierType o_Type;

private:
    // Methods

    // Attributes
};

But when I try to compile this code I get a long list of errors:

/home/gayanm/street/src/QueryServer_NEW/ITier.h:60: error: expected nested-name-specifier /home/gayanm/street/src/QueryServer_NEW/ITier.h:60: error: ITier<T>' specified as declarator-id /home/gayanm/street/src/QueryServer_NEW/ITier.h:60: error: perhaps you want ITier' for a constructor /home/gayanm/street/src/QueryServer_NEW/ITier.h:60: error: two or more data types in declaration of ITier<T>' /home/gayanm/street/src/QueryServer_NEW/ITier.h:60: error: expected ;' before "ParamITier" /home/gayanm/street/src/QueryServer_NEW/ITier.h:83: error: ParamITier' was not declared in this scope /home/gayanm/street/src/QueryServer_NEW/ITier.h:83: error: template argument 2 is invalid /home/gayanm/street/src/QueryServer_NEW/ITier.h:83: error: template argument 4 is invalid /home/gayanm/street/src/QueryServer_NEW/ITier.h:83: error: ISO C++ forbids declaration of map_Tiers' with no type /home/gayanm/street/src/QueryServer_NEW/ITier.h: In member function ITier<T>* ITier<T>::Get(T)': /home/gayanm/street/src/QueryServer_NEW/ITier.h:64: error: ParamITier' undeclared (first use this function) /home/gayanm/street/src/QueryServer_NEW/ITier.h:64: error: (Each undeclared identifier is reported only once for each function it appears in.) /home/gayanm/street/src/QueryServer_NEW/ITier.h:64: error: template argument 2 is invalid /home/gayanm/street/src/QueryServer_NEW/ITier.h:64: error: template argument 4 is invalid /home/gayanm/street/src/QueryServer_NEW/ITier.h:64: erro r: expected ;' before '::' token /home/gayanm/street/src/QueryServer_NEW/ITier.h:66: error: ;' before '::' token /home/gayanm/street/src/QueryServer_NEW/ITier.h:66: error: it' undeclared (first use this function) /home/gayanm/street/src/QueryServer_NEW/ITier.h:66: error: request for member end' in ((ITier )this)->ITier::map_Tiers', which is of non-class type int' /home/gayanm/street/src/QueryServer_NEW/ITier.h: In member function void ITier::Set(T, ITier )': /home/gayanm/street/src/QueryServer_NEW/ITier.h:74: error: request for member insert' in ((ITier*)this)->ITier::map_Tiers', which is of non-class type int' /home/gayanm/street/src/QueryServer_NEW/ITier.h:74: error: pair' undeclared (first use this function) /home/gayanm/street/src/QueryServer_NEW/ITier.h:74: error: expected primary-expression before ',' token /home/gayanm/street/src/QueryServer_NEW/ITier.h:74: error: ParamITier' undeclared (first use this function) /home/gayanm/street/src/QueryServer_NEW/ITier.h:74: error: expected primary-expression before '>' token /home/gayanm/street/src/QueryServer_NEW/ITier.h: At global scope: /home/gayanm/street/src/QueryServer_NEW/ITier.h:93: error: base ParamITier' undeclared (first use this function) /home/gayanm/street/src/QueryServer_NEW/ITier.h:74: error: expected primary-expression before '>' token /home/gayanm/street/src/QueryServer_NEW/ITier.h: At global scope: /home/gayanm/street/src/QueryServer_NEW/ITier.h:93: error: base ITier' with only non-default constructor in class without a constructor /home/gayanm/street/src/QueryServer_NEW/ITier.h:109: error: expected class-name before '{' token

Could you please point out how to fix these?

Thank You.

Line 60 does not access a depending name. What you use is ITier<T> of which the compiler knows it's a template given an argument. Instead of typename you want to use typedef ;)

Line 64 does access the depending name iterator which is a type-name, so you have to put typename before std::map . I put the two disambiguations, template and typename on this answer: Disambiguations of dependent names .

Line 74 would be right, if you fix the bug in Line 60, as far as i can see.

Line 83 is alright in itself as far as i can see.

另外,我建议您将const T&传递给函数而不是T ,因为您不能确定(这是模板参数!)它将是“便宜”的副本。

Thanks a lot litb. I was able to fix my code with the guidelines you provided.

class IStatMsg;

template <typename T>
class ITier
{
public:

    // Methods
    ITier(){};
    ITier(TierType oType) : o_Type(oType){};
    virtual ~ITier(){};

    //typename ITier<T> ParamITier; 

    ITier<T>* Get(T oKey)
    {
        typename std::map<T, ITier<T>*>::iterator it = map_Tiers.find(oKey);    

        if (it != map_Tiers.end())
            return it->second;

        return NULL;
    }

    void Set(T oKey, ITier<T>* pTier)
    {
        map_Tiers.insert(std::pair<T, ITier<T>*>(oKey, pTier));
    }

    TierType GetType() { return o_Type; }

protected:
    // Methods

    // Attributes
    std::map<T, ITier<T>*> map_Tiers;
    TierType o_Type;

private:
    // Methods

    // Attributes
};

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