简体   繁体   中英

Need scope resolution operator to call member function template when class template exists with same name

I have a class template that happens to have the same name as a member function template of some classes. Now another function template gets instantiated with one of the classes with the member function template in question. To call the member function template within this function template I need to use the template keyword, I understand this and have no problem with that. However, I need to use the scope resolution operator (I just found out that's what that's called) :: to specify I mean the class' member function template and not the class template and I don't understand why.

That's a lot of templated things so let me give an example:

    //class with same name as member function below.
    //must be class template or error doesn't show up.
    //also no error if this is a function template instead of class
    template <class T>
    struct f
    {
    };

    struct Base
    {
        //function with same name as struct above,
        //no error if this is not templated
        template <int N>
        void f(){}
    };

    //template function that will be instantiated with T=Base.
    //no error if this is not templated
    template <class T>
    void g(T t)
    {
        //I understand why template keyword is needed here,
        //but not why T:: is needed
        t.T::template f<0>();
        //t.template f<0>(); gives error.
    }

The error in question is (from g++-4.7)

    error: type/value mismatch at argument 1 in template parameter list for ‘template<class T> struct f’
    error:   expected a type, got ‘0’

It seems the compiler parses f<0>() on the commented out line (without scope resolution operator) as trying to instantiate an object of type struct f<0> . I don't know why it is doing this, I thought it should be able to see from the t.template that I'm trying to access the member function template.

I'd like to understand what is going on here, why is T:: needed in this case, other than to placate the compiler?

It seems that there is no problem under MSVC and Clang, so it seems to a g++-specific issue.

I think it has to do with Two phase lookup . Especially Steve Jessops notes in the answer are are important.

This might work

template <class T>
void g(T t)
{
    t.T::template f<0>(); 
}

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