简体   繁体   中英

Dependent name lookup in base class template

I understand that a lookup for a dependent member/typedef will not be performed on a dependent base class template and that I have have to explicitly prefix with this->member in the case of a base member, or typename base<T...>::sometype for a typedef/using on the base class.

All of the answers I can find suggest using typename base<T...>::sometype . This can obviously be a typedef in the derived class like using base_type = base<T...> and then typename base_type::some_type everywhere, but this then requires repetition of the base class arguments in both the deriviation, and the typedef.

However, it does appear to work when I use derived::sometype , rather then specifying the base class. for example

template <typename T>
struct base
{
    using type = T*;

};

template <typename T>
struct derived : base<T>
{
    derived ()
    {
        typename derived::type l; // <- Here  
    }
};

int main() {

    derived <int> v;
    return 0;
}

This allows me to use the injected class name , and importantly saves me any repetition of template arguments anywhere but the class definition, and base derivation.

From this answer it appears to me that the compiler just needs to know that the name is a dependent name in order for the lookup to be done in the second stage, and using the derived name appears serves this purpose?

As all of the answers I found suggested using base<T...> for dependent names, I am interested to know if there are any problems with using the injected class name to access dependent types in the base?

Edit:

It appears the base class name is also injected, and so using base_type = derived::base; is all that is needed in order to not have to repeat the base class types. At least when the name of the base class is known.

Interestingly there was a proposal in 2009 to be able to alias base classes, which would solved the problem when the name of the base class is not know, or multiple specializations of the same base were inherited from. Although the proposal was rejected saying "Encourage the paper author to continue to the direction of a more general solution".

Discussing this elsewhere it was suggested that something like this would provide a more general solution, and would allow bases to be aliased and their injected name used. However this has not been proposed as far as I know.

template <typename T> using TD = typename std::decay<T>, using std::swap
void fun(TD x) noexcept(swap(x, x)) { ... }

There would only be a problem if there is disagreement about what the member name means. So long as only the base defines the name then there will be no problems but if the derived type redefines it to be something else then the derived member will be chosen.

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