Search code examples
c++templateslanguage-lawyerusingdependent-name

Using-declaration to introduce dependent name from base class template


To use a name from dependent base class in derived class template (e.g. B<T>), one has to add a prefix highlighting to the compiler that is a dependent name (B<T>::). And to avoid doing it many times, a using-declaration can be used instead.

Below code with such using-declaration:

template <class T>
struct A {
    constexpr static int x = 0;
};

template <class T>
struct B : A<T> {
    // ok everywhere
    constexpr static int y = B<T>::x;

    // ok in MSVC
    using B<T>::x;
    constexpr static int z = x;
};

is found to work fine in MSVC compiler, while others do not like it. Clang in particular complains

error: no member named 'x' in 'B'

Hovewer Clang does not see any error in y = B<T>::x one line above. Online demo: https://gcc.godbolt.org/z/PvKW753M8

Which implementation is correct here and why?


Solution

  • The program is IFNDR (ill-formed, no diagnostic required).

    This is because you never instantiate any specialization, but every instantiation of a specialization of B would be ill-formed. See [temp.res.general]/6.1.

    Every instantiation would be ill-formed because B<T> names the current instantiation, i.e. the current class, not a base class of it, but the left-hand side of the nested-name-specifier in a using declaration in a class scope must name a base of the current class (or the whole name must name an enumerator). See [namespace.udecl]/3.