Osyotr
Osyotr

Reputation: 1152

Proper way to inherit base class constructor using type aliases?

I'm trying to inherit constructor of a template base class with a very lengthy name. For this base class I introduced type alias. (https://godbolt.org/z/aqf6czPdo)

class Object {};
class Gadget {};

class SuperBase : public Object { using base_t = Object; };
class Params : public Gadget { using base_t = Gadget; };

template<class T, class TParams>
class Base : public SuperBase, public TParams {};

template<class T>
class Derived : public Base<T, Params>
{
    using base_t = Base<T, Params>;
public:
    using base_t::base_t;
};

This code compiles successfully using GCC and Clang, but does not compile with MSVC /permissive- flag with

error C2385: ambiguous access of 'base_t'
note: could be the 'base_t' in base 'SuperBase'
note: or could be the 'base_t' in base 'Params'

If I write it like using base_t::Base;, then MSVC compiles successfully, but clang fails. Using full base class name using Base<T, Params>::Base; works for all three compilers.

The question is what compiler is correct in this case?

I've expected that all three compilers would compile this code successfully. Many answers on stackoverflow suggest that type aliases can in fact be used to inherit base class constructors.

Upvotes: 5

Views: 321

Answers (1)

Davis Herring
Davis Herring

Reputation: 39778

This is an MSVC bug: [class.qual]/1.2 (/2.2 in C++20) says clearly that the same name appearing on either side of the :: indicates inheriting constructors. The current wording restricts this lexical treatment to dependent using-declarators ([namespace.udecl]/1), but of course this one is. (The injected-class-name is the trigger for non-dependent names, since constructors can’t directly be found by name lookup at all.)

Upvotes: 4

Related Questions