英文:
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.
英文:
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.
答案1
得分: 4
这是一个MSVC的bug:[class.qual]/1.2(在C++20中是/2.2)清楚地指出::
两侧出现相同的名称表示继承构造函数。当前的措辞将此词法处理限制为相关的using-declarator([namespace.udecl]/1),但当然这个是相关的(因为通过名称查找不能直接找到构造函数)。
英文:
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.)
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论