Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
414 views
in Technique[技术] by (71.8m points)

c++ - "typename" and "template" keywords: are they really necessary?

There are a lot of questions at this site with the problems while compiling c++ template code. One of the most common solutions to such problems is to add typename (and, less frequently, template) keyword in the right places of the program code:

template<typename T>
class Base
{
public:

    typedef char SomeType;

    template<typename U>
    void SomeMethod(SomeType& v)
    {
        // ...
    }

};

template<typename T>
class Derived : public Base<T>
{
public:

    void Method()
    {
        typename Base<T>::SomeType x;
    //  ^^^^^^^^

        this->template SomeMethod<int>(x);
    //        ^^^^^^^^
    }
};

Whether there is a code that compiles both with and without keyword typename and gives different results (e.g. output strings)? Similar question for template keyword.

If not, whether these keywords are really necessary in such meanings?

A small overview of the current situation

@Paul Evans wrote a good answer but it is more suitable for the question "Where and why do I have to put the “template” and “typename” keywords?", not for my question.

@Simple gave an example of the required code for typename keyword and its possible variation. @Jarod42 gave another variation without any templates, which is probably a gcc bug because it does not compile with clang.

@n.m. gave an example of the required code for template keyword, @dyp improved it. @n.m. also wrote the another code for both keywords using SFINAE.

@James Kanze in his answer argues that it is impossible to write the required code and any attempts to do it will result in undefined behavior. So the above examples of code are illegal.

It is interesting to find out who is right and what the C++ standard says about this.

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

The rule is: typename has to be used whenever a name that depends on a template parameter is a type. There are clear cases where it's needed, consider

template <typename T> 
class Foo { 
    typename T::type * p; 
    //... 
}; 

Here, the second typename is used to indicate that type is a type defined within class T. Thus, p is a pointer to the type T::type.

Without typename, type would be considered a member of class T. So the expression:

T::type * p

would be a multiplication of the type member of class T with p.

Similarly, the rule is: .template, ->template or ::template must be used when accessing a template member that uses a template parameter. Consider:

 p->template SomeMethod<int>(x);

without the use of template, the compiler does not know that the < token is not less-than but the start of a template argument list.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...