Officially, what is typename for?

后端 未结 8 1644
野的像风
野的像风 2020-11-22 15:07

On occasion I\'ve seen some really indecipherable error messages spit out by gcc when using templates... Specifically, I\'ve had problems where seemingly correc

8条回答
  •  没有蜡笔的小新
    2020-11-22 15:31

    The secret lies in the fact that a template can be specialized for some types. This means it also can define the interface completely different for several types. For example you can write:

    template
    struct test {
        typedef T* ptr;
    };
    
    template<>         // complete specialization 
    struct test { // for the case T is int
        T* ptr;
    };
    

    One might ask why is this useful and indeed: That really looks useless. But take in mind that for example std::vector the reference type looks completely different than for other Ts. Admittedly it doesn't change the kind of reference from a type to something different but nevertheless it could happen.

    Now what happens if you write your own templates using this test template. Something like this

    template
    void print(T& x) {
        test::ptr p = &x;
        std::cout << *p << std::endl;
    }
    

    it seems to be ok for you because you expect that test::ptr is a type. But the compiler doesn't know and in deed he is even advised by the standard to expect the opposite, test::ptr isn't a type. To tell the compiler what you expect you have to add a typename before. The correct template looks like this

    template
    void print(T& x) {
        typename test::ptr p = &x;
        std::cout << *p << std::endl;
    }
    

    Bottom line: You have to add typename before whenever you use a nested type of a template in your templates. (Of course only if a template parameter of your template is used for that inner template.)

提交回复
热议问题