使用类型别名正确继承基类构造函数的方式?

huangapple go评论74阅读模式
英文:

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&lt;class T, class TParams&gt;
class Base : public SuperBase, public TParams {};

template&lt;class T&gt;
class Derived : public Base&lt;T, Params&gt;
{
    using base_t = Base&lt;T, Params&gt;;
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 &#39;base_t&#39;
note: could be the &#39;base_t&#39; in base &#39;SuperBase&#39;
note: or could be the &#39;base_t&#39; in base &#39;Params&#39;

If I write it like using base_t::Base;, then MSVC compiles successfully, but clang fails. Using full base class name using Base&lt;T, Params&gt;::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.)

huangapple
  • 本文由 发表于 2023年3月31日 22:20:11
  • 转载请务必保留本文链接:https://go.coder-hub.com/75899617.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定