Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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?

like image 770
Fedor Avatar asked May 17 '26 02:05

Fedor


1 Answers

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.

like image 115
user17732522 Avatar answered May 18 '26 15:05

user17732522



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!