Reputation: 1152
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
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